Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
dd3cc966
R
Rust
项目概览
int
/
Rust
12 个月 前同步成功
通知
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,发现更多精彩内容 >>
提交
dd3cc966
编写于
8月 31, 2018
作者:
N
Niko Matsakis
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
add the `AscribeUserType` statement kind
Make it have the semantics of subtype.
上级
22f9bcce
变更
22
显示空白变更内容
内联
并排
Showing
22 changed file
with
134 addition
and
78 deletion
+134
-78
src/librustc/ich/impls_mir.rs
src/librustc/ich/impls_mir.rs
+2
-2
src/librustc/mir/mod.rs
src/librustc/mir/mod.rs
+9
-17
src/librustc/mir/visit.rs
src/librustc/mir/visit.rs
+15
-13
src/librustc/ty/context.rs
src/librustc/ty/context.rs
+2
-2
src/librustc_codegen_llvm/mir/statement.rs
src/librustc_codegen_llvm/mir/statement.rs
+1
-1
src/librustc_mir/borrow_check/mod.rs
src/librustc_mir/borrow_check/mod.rs
+2
-2
src/librustc_mir/borrow_check/nll/constraint_generation.rs
src/librustc_mir/borrow_check/nll/constraint_generation.rs
+3
-3
src/librustc_mir/borrow_check/nll/invalidation.rs
src/librustc_mir/borrow_check/nll/invalidation.rs
+2
-2
src/librustc_mir/borrow_check/nll/renumber.rs
src/librustc_mir/borrow_check/nll/renumber.rs
+7
-3
src/librustc_mir/borrow_check/nll/type_check/mod.rs
src/librustc_mir/borrow_check/nll/type_check/mod.rs
+24
-9
src/librustc_mir/borrow_check/nll/type_check/relate_tys.rs
src/librustc_mir/borrow_check/nll/type_check/relate_tys.rs
+46
-3
src/librustc_mir/dataflow/impls/borrows.rs
src/librustc_mir/dataflow/impls/borrows.rs
+1
-1
src/librustc_mir/dataflow/move_paths/builder.rs
src/librustc_mir/dataflow/move_paths/builder.rs
+1
-1
src/librustc_mir/interpret/step.rs
src/librustc_mir/interpret/step.rs
+1
-1
src/librustc_mir/transform/check_unsafety.rs
src/librustc_mir/transform/check_unsafety.rs
+1
-1
src/librustc_mir/transform/cleanup_post_borrowck.rs
src/librustc_mir/transform/cleanup_post_borrowck.rs
+10
-10
src/librustc_mir/transform/mod.rs
src/librustc_mir/transform/mod.rs
+2
-2
src/librustc_mir/transform/qualify_consts.rs
src/librustc_mir/transform/qualify_consts.rs
+1
-1
src/librustc_mir/transform/remove_noop_landing_pads.rs
src/librustc_mir/transform/remove_noop_landing_pads.rs
+1
-1
src/librustc_mir/transform/rustc_peek.rs
src/librustc_mir/transform/rustc_peek.rs
+1
-1
src/librustc_passes/mir_stats.rs
src/librustc_passes/mir_stats.rs
+1
-1
src/test/mir-opt/basic_assignment.rs
src/test/mir-opt/basic_assignment.rs
+1
-1
未找到文件。
src/librustc/ich/impls_mir.rs
浏览文件 @
dd3cc966
...
@@ -255,9 +255,9 @@ fn hash_stable<W: StableHasherResult>(&self,
...
@@ -255,9 +255,9 @@ fn hash_stable<W: StableHasherResult>(&self,
op
.hash_stable
(
hcx
,
hasher
);
op
.hash_stable
(
hcx
,
hasher
);
places
.hash_stable
(
hcx
,
hasher
);
places
.hash_stable
(
hcx
,
hasher
);
}
}
mir
::
StatementKind
::
UserAssertTy
(
ref
c_ty
,
ref
local
)
=>
{
mir
::
StatementKind
::
AscribeUserType
(
ref
place
,
ref
c_ty
)
=>
{
place
.hash_stable
(
hcx
,
hasher
);
c_ty
.hash_stable
(
hcx
,
hasher
);
c_ty
.hash_stable
(
hcx
,
hasher
);
local
.hash_stable
(
hcx
,
hasher
);
}
}
mir
::
StatementKind
::
Nop
=>
{}
mir
::
StatementKind
::
Nop
=>
{}
mir
::
StatementKind
::
InlineAsm
{
ref
asm
,
ref
outputs
,
ref
inputs
}
=>
{
mir
::
StatementKind
::
InlineAsm
{
ref
asm
,
ref
outputs
,
ref
inputs
}
=>
{
...
...
src/librustc/mir/mod.rs
浏览文件 @
dd3cc966
...
@@ -1636,22 +1636,14 @@ pub enum StatementKind<'tcx> {
...
@@ -1636,22 +1636,14 @@ pub enum StatementKind<'tcx> {
/// (The starting point(s) arise implicitly from borrows.)
/// (The starting point(s) arise implicitly from borrows.)
EndRegion
(
region
::
Scope
),
EndRegion
(
region
::
Scope
),
/// Encodes a user's type as
sertion. These need to be preserved intact so that NLL can respect
/// Encodes a user's type as
cription. These need to be preserved
/// them. For example:
///
intact so that NLL can respect
them. For example:
///
///
/// let
(a, b): (T, U)
= y;
/// let
a: T
= y;
///
///
/// Here we would insert a `UserAssertTy<(T, U)>(y)` instruction to check that the type of `y`
/// Here we would insert a `AscribeUserType` that ensures that the
/// is the right thing.
/// type `Y` of `y` is a subtype of `T` (`Y <: T`).
///
AscribeUserType
(
Place
<
'tcx
>
,
CanonicalTy
<
'tcx
>
),
/// `CanonicalTy` is used to capture "inference variables" from the user's types. For example:
///
/// let x: Vec<_> = ...;
/// let y: &u32 = ...;
///
/// would result in `Vec<?0>` and `&'?0 u32` respectively (where `?0` is a canonicalized
/// variable).
UserAssertTy
(
CanonicalTy
<
'tcx
>
,
Local
),
/// No-op. Useful for deleting instructions without affecting statement indices.
/// No-op. Useful for deleting instructions without affecting statement indices.
Nop
,
Nop
,
...
@@ -1728,8 +1720,8 @@ fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
...
@@ -1728,8 +1720,8 @@ fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
ref
outputs
,
ref
outputs
,
ref
inputs
,
ref
inputs
,
}
=>
write!
(
fmt
,
"asm!({:?} : {:?} : {:?})"
,
asm
,
outputs
,
inputs
),
}
=>
write!
(
fmt
,
"asm!({:?} : {:?} : {:?})"
,
asm
,
outputs
,
inputs
),
UserAssertTy
(
ref
c_ty
,
ref
local
)
=>
{
AscribeUserType
(
ref
place
,
ref
c_ty
)
=>
{
write!
(
fmt
,
"
UserAssertTy({:?}, {:?})"
,
c_ty
,
local
)
write!
(
fmt
,
"
AscribeUserType({:?}, {:?})"
,
place
,
c_ty
)
}
}
Nop
=>
write!
(
fmt
,
"nop"
),
Nop
=>
write!
(
fmt
,
"nop"
),
}
}
...
@@ -2652,7 +2644,7 @@ impl<'tcx> TypeFoldable<'tcx> for StatementKind<'tcx> {
...
@@ -2652,7 +2644,7 @@ impl<'tcx> TypeFoldable<'tcx> for StatementKind<'tcx> {
(
StatementKind
::
InlineAsm
)
{
asm
,
outputs
,
inputs
},
(
StatementKind
::
InlineAsm
)
{
asm
,
outputs
,
inputs
},
(
StatementKind
::
Validate
)(
a
,
b
),
(
StatementKind
::
Validate
)(
a
,
b
),
(
StatementKind
::
EndRegion
)(
a
),
(
StatementKind
::
EndRegion
)(
a
),
(
StatementKind
::
UserAssertTy
)(
a
,
b
),
(
StatementKind
::
AscribeUserType
)(
a
,
b
),
(
StatementKind
::
Nop
),
(
StatementKind
::
Nop
),
}
}
}
}
...
...
src/librustc/mir/visit.rs
浏览文件 @
dd3cc966
...
@@ -144,11 +144,11 @@ fn visit_operand(&mut self,
...
@@ -144,11 +144,11 @@ fn visit_operand(&mut self,
self
.super_operand
(
operand
,
location
);
self
.super_operand
(
operand
,
location
);
}
}
fn
visit_user_assert_ty
(
&
mut
self
,
fn
visit_ascribe_user_ty
(
&
mut
self
,
place
:
&
$
(
$mutability
)
*
Place
<
'tcx
>
,
c_ty
:
&
$
(
$mutability
)
*
CanonicalTy
<
'tcx
>
,
c_ty
:
&
$
(
$mutability
)
*
CanonicalTy
<
'tcx
>
,
local
:
&
$
(
$mutability
)
*
Local
,
location
:
Location
)
{
location
:
Location
)
{
self
.super_
user_assert_ty
(
c_ty
,
local
,
location
);
self
.super_
ascribe_user_ty
(
place
,
c_ty
,
location
);
}
}
fn
visit_place
(
&
mut
self
,
fn
visit_place
(
&
mut
self
,
...
@@ -386,9 +386,11 @@ fn super_statement(&mut self,
...
@@ -386,9 +386,11 @@ fn super_statement(&mut self,
self
.visit_operand
(
input
,
location
);
self
.visit_operand
(
input
,
location
);
}
}
}
}
StatementKind
::
UserAssertTy
(
ref
$
(
$mutability
)
*
c_ty
,
StatementKind
::
AscribeUserType
(
ref
$
(
$mutability
)
*
local
)
=>
{
ref
$
(
$mutability
)
*
place
,
self
.visit_user_assert_ty
(
c_ty
,
local
,
location
);
ref
$
(
$mutability
)
*
c_ty
,
)
=>
{
self
.visit_ascribe_user_ty
(
place
,
c_ty
,
location
);
}
}
StatementKind
::
Nop
=>
{}
StatementKind
::
Nop
=>
{}
}
}
...
@@ -629,12 +631,12 @@ fn super_operand(&mut self,
...
@@ -629,12 +631,12 @@ fn super_operand(&mut self,
}
}
}
}
fn
super_user_assert_ty
(
&
mut
self
,
fn
super_ascribe_user_ty
(
&
mut
self
,
place
:
&
$
(
$mutability
)
*
Place
<
'tcx
>
,
c_ty
:
&
$
(
$mutability
)
*
CanonicalTy
<
'tcx
>
,
c_ty
:
&
$
(
$mutability
)
*
CanonicalTy
<
'tcx
>
,
local
:
&
$
(
$mutability
)
*
Local
,
location
:
Location
)
{
location
:
Location
)
{
self
.visit_place
(
place
,
PlaceContext
::
Validate
,
location
);
self
.visit_canonical_ty
(
c_ty
);
self
.visit_canonical_ty
(
c_ty
);
self
.visit_local
(
local
,
PlaceContext
::
Validate
,
location
);
}
}
fn
super_place
(
&
mut
self
,
fn
super_place
(
&
mut
self
,
...
...
src/librustc/ty/context.rs
浏览文件 @
dd3cc966
...
@@ -356,8 +356,8 @@ pub struct TypeckTables<'tcx> {
...
@@ -356,8 +356,8 @@ pub struct TypeckTables<'tcx> {
/// belongs, but it may not exist if it's a tuple field (`tuple.0`).
/// belongs, but it may not exist if it's a tuple field (`tuple.0`).
field_indices
:
ItemLocalMap
<
usize
>
,
field_indices
:
ItemLocalMap
<
usize
>
,
/// Stores the canonicalized types provided by the user. See also
`UserAssertTy` statement in
/// Stores the canonicalized types provided by the user. See also
/// MIR.
///
`AscribeUserType` statement in
MIR.
user_provided_tys
:
ItemLocalMap
<
CanonicalTy
<
'tcx
>>
,
user_provided_tys
:
ItemLocalMap
<
CanonicalTy
<
'tcx
>>
,
/// Stores the types for various nodes in the AST. Note that this table
/// Stores the types for various nodes in the AST. Note that this table
...
...
src/librustc_codegen_llvm/mir/statement.rs
浏览文件 @
dd3cc966
...
@@ -92,7 +92,7 @@ pub fn codegen_statement(&mut self,
...
@@ -92,7 +92,7 @@ pub fn codegen_statement(&mut self,
mir
::
StatementKind
::
ReadForMatch
(
_
)
|
mir
::
StatementKind
::
ReadForMatch
(
_
)
|
mir
::
StatementKind
::
EndRegion
(
_
)
|
mir
::
StatementKind
::
EndRegion
(
_
)
|
mir
::
StatementKind
::
Validate
(
..
)
|
mir
::
StatementKind
::
Validate
(
..
)
|
mir
::
StatementKind
::
UserAssertTy
(
..
)
|
mir
::
StatementKind
::
AscribeUserType
(
..
)
|
mir
::
StatementKind
::
Nop
=>
bx
,
mir
::
StatementKind
::
Nop
=>
bx
,
}
}
}
}
...
...
src/librustc_mir/borrow_check/mod.rs
浏览文件 @
dd3cc966
...
@@ -535,10 +535,10 @@ fn visit_statement_entry(
...
@@ -535,10 +535,10 @@ fn visit_statement_entry(
// flow_state already handled).
// flow_state already handled).
}
}
StatementKind
::
Nop
StatementKind
::
Nop
|
StatementKind
::
UserAssertTy
(
..
)
|
StatementKind
::
AscribeUserType
(
..
)
|
StatementKind
::
Validate
(
..
)
|
StatementKind
::
Validate
(
..
)
|
StatementKind
::
StorageLive
(
..
)
=>
{
|
StatementKind
::
StorageLive
(
..
)
=>
{
// `Nop`, `
UserAssertTy
`, `Validate`, and `StorageLive` are irrelevant
// `Nop`, `
AscribeUserType
`, `Validate`, and `StorageLive` are irrelevant
// to borrow check.
// to borrow check.
}
}
StatementKind
::
StorageDead
(
local
)
=>
{
StatementKind
::
StorageDead
(
local
)
=>
{
...
...
src/librustc_mir/borrow_check/nll/constraint_generation.rs
浏览文件 @
dd3cc966
...
@@ -17,7 +17,7 @@
...
@@ -17,7 +17,7 @@
use
rustc
::
mir
::
visit
::
TyContext
;
use
rustc
::
mir
::
visit
::
TyContext
;
use
rustc
::
mir
::
visit
::
Visitor
;
use
rustc
::
mir
::
visit
::
Visitor
;
use
rustc
::
mir
::{
BasicBlock
,
BasicBlockData
,
Location
,
Mir
,
Place
,
Rvalue
};
use
rustc
::
mir
::{
BasicBlock
,
BasicBlockData
,
Location
,
Mir
,
Place
,
Rvalue
};
use
rustc
::
mir
::{
Local
,
Statement
,
Terminator
};
use
rustc
::
mir
::{
Statement
,
Terminator
};
use
rustc
::
ty
::
fold
::
TypeFoldable
;
use
rustc
::
ty
::
fold
::
TypeFoldable
;
use
rustc
::
ty
::
subst
::
Substs
;
use
rustc
::
ty
::
subst
::
Substs
;
use
rustc
::
ty
::{
self
,
CanonicalTy
,
ClosureSubsts
,
GeneratorSubsts
,
RegionVid
};
use
rustc
::
ty
::{
self
,
CanonicalTy
,
ClosureSubsts
,
GeneratorSubsts
,
RegionVid
};
...
@@ -175,10 +175,10 @@ fn visit_terminator(
...
@@ -175,10 +175,10 @@ fn visit_terminator(
self
.super_terminator
(
block
,
terminator
,
location
);
self
.super_terminator
(
block
,
terminator
,
location
);
}
}
fn
visit_
user_assert
_ty
(
fn
visit_
ascribe_user
_ty
(
&
mut
self
,
&
mut
self
,
_
place
:
&
Place
<
'tcx
>
,
_
c_ty
:
&
CanonicalTy
<
'tcx
>
,
_
c_ty
:
&
CanonicalTy
<
'tcx
>
,
_
local
:
&
Local
,
_
location
:
Location
,
_
location
:
Location
,
)
{
)
{
}
}
...
...
src/librustc_mir/borrow_check/nll/invalidation.rs
浏览文件 @
dd3cc966
...
@@ -144,10 +144,10 @@ fn visit_statement(&mut self,
...
@@ -144,10 +144,10 @@ fn visit_statement(&mut self,
// EndRegion matters to older NLL/MIR AST borrowck, not to alias NLL
// EndRegion matters to older NLL/MIR AST borrowck, not to alias NLL
StatementKind
::
EndRegion
(
..
)
|
StatementKind
::
EndRegion
(
..
)
|
StatementKind
::
Nop
|
StatementKind
::
Nop
|
StatementKind
::
UserAssertTy
(
..
)
|
StatementKind
::
AscribeUserType
(
..
)
|
StatementKind
::
Validate
(
..
)
|
StatementKind
::
Validate
(
..
)
|
StatementKind
::
StorageLive
(
..
)
=>
{
StatementKind
::
StorageLive
(
..
)
=>
{
// `Nop`, `
UserAssertTy
`, `Validate`, and `StorageLive` are irrelevant
// `Nop`, `
AscribeUserType
`, `Validate`, and `StorageLive` are irrelevant
// to borrow check.
// to borrow check.
}
}
StatementKind
::
StorageDead
(
local
)
=>
{
StatementKind
::
StorageDead
(
local
)
=>
{
...
...
src/librustc_mir/borrow_check/nll/renumber.rs
浏览文件 @
dd3cc966
...
@@ -10,7 +10,7 @@
...
@@ -10,7 +10,7 @@
use
rustc
::
ty
::
subst
::
Substs
;
use
rustc
::
ty
::
subst
::
Substs
;
use
rustc
::
ty
::{
self
,
CanonicalTy
,
ClosureSubsts
,
GeneratorSubsts
,
Ty
,
TypeFoldable
};
use
rustc
::
ty
::{
self
,
CanonicalTy
,
ClosureSubsts
,
GeneratorSubsts
,
Ty
,
TypeFoldable
};
use
rustc
::
mir
::{
BasicBlock
,
Loca
l
,
Location
,
Mir
,
Statement
,
StatementKind
};
use
rustc
::
mir
::{
BasicBlock
,
Loca
tion
,
Mir
,
Place
,
Statement
,
StatementKind
};
use
rustc
::
mir
::
visit
::{
MutVisitor
,
TyContext
};
use
rustc
::
mir
::
visit
::{
MutVisitor
,
TyContext
};
use
rustc
::
infer
::{
InferCtxt
,
NLLRegionVariableOrigin
};
use
rustc
::
infer
::{
InferCtxt
,
NLLRegionVariableOrigin
};
...
@@ -112,8 +112,12 @@ fn visit_closure_substs(&mut self, substs: &mut ClosureSubsts<'tcx>, location: L
...
@@ -112,8 +112,12 @@ fn visit_closure_substs(&mut self, substs: &mut ClosureSubsts<'tcx>, location: L
debug!
(
"visit_closure_substs: substs={:?}"
,
substs
);
debug!
(
"visit_closure_substs: substs={:?}"
,
substs
);
}
}
fn
visit_user_assert_ty
(
&
mut
self
,
_
c_ty
:
&
mut
CanonicalTy
<
'tcx
>
,
_
local
:
&
mut
Local
,
fn
visit_ascribe_user_ty
(
_
location
:
Location
)
{
&
mut
self
,
_
place
:
&
mut
Place
<
'tcx
>
,
_
c_ty
:
&
mut
CanonicalTy
<
'tcx
>
,
_
location
:
Location
,
)
{
// User-assert-ty statements represent types that the user added explicitly.
// User-assert-ty statements represent types that the user added explicitly.
// We don't want to erase the regions from these types: rather, we want to
// We don't want to erase the regions from these types: rather, we want to
// add them as constraints at type-check time.
// add them as constraints at type-check time.
...
...
src/librustc_mir/borrow_check/nll/type_check/mod.rs
浏览文件 @
dd3cc966
...
@@ -248,7 +248,7 @@ fn visit_constant(&mut self, constant: &Constant<'tcx>, location: Location) {
...
@@ -248,7 +248,7 @@ fn visit_constant(&mut self, constant: &Constant<'tcx>, location: Location) {
if
let
Some
(
user_ty
)
=
constant
.user_ty
{
if
let
Some
(
user_ty
)
=
constant
.user_ty
{
if
let
Err
(
terr
)
=
if
let
Err
(
terr
)
=
self
.cx
self
.cx
.eq_
canonical
_type_and_type
(
user_ty
,
constant
.ty
,
location
.boring
())
.eq_
user
_type_and_type
(
user_ty
,
constant
.ty
,
location
.boring
())
{
{
span_mirbug!
(
span_mirbug!
(
self
,
self
,
...
@@ -850,13 +850,28 @@ fn eq_types(&mut self, a: Ty<'tcx>, b: Ty<'tcx>, locations: Locations) -> Fallib
...
@@ -850,13 +850,28 @@ fn eq_types(&mut self, a: Ty<'tcx>, b: Ty<'tcx>, locations: Locations) -> Fallib
)
)
}
}
fn
eq_canonical_type_and_type
(
fn
sub_type_and_user_type
(
&
mut
self
,
a
:
Ty
<
'tcx
>
,
b
:
CanonicalTy
<
'tcx
>
,
locations
:
Locations
,
)
->
Fallible
<
()
>
{
relate_tys
::
sub_type_and_user_type
(
self
.infcx
,
a
,
b
,
locations
,
self
.borrowck_context
.as_mut
()
.map
(|
x
|
&
mut
**
x
),
)
}
fn
eq_user_type_and_type
(
&
mut
self
,
&
mut
self
,
a
:
CanonicalTy
<
'tcx
>
,
a
:
CanonicalTy
<
'tcx
>
,
b
:
Ty
<
'tcx
>
,
b
:
Ty
<
'tcx
>
,
locations
:
Locations
,
locations
:
Locations
,
)
->
Fallible
<
()
>
{
)
->
Fallible
<
()
>
{
relate_tys
::
eq_
canonical
_type_and_type
(
relate_tys
::
eq_
user
_type_and_type
(
self
.infcx
,
self
.infcx
,
a
,
a
,
b
,
b
,
...
@@ -905,7 +920,7 @@ fn check_stmt(&mut self, mir: &Mir<'tcx>, stmt: &Statement<'tcx>, location: Loca
...
@@ -905,7 +920,7 @@ fn check_stmt(&mut self, mir: &Mir<'tcx>, stmt: &Statement<'tcx>, location: Loca
}
}
if
let
Some
(
user_ty
)
=
self
.rvalue_user_ty
(
rv
)
{
if
let
Some
(
user_ty
)
=
self
.rvalue_user_ty
(
rv
)
{
if
let
Err
(
terr
)
=
self
.eq_
canonical
_type_and_type
(
if
let
Err
(
terr
)
=
self
.eq_
user
_type_and_type
(
user_ty
,
user_ty
,
rv_ty
,
rv_ty
,
location
.boring
(),
location
.boring
(),
...
@@ -955,15 +970,15 @@ fn check_stmt(&mut self, mir: &Mir<'tcx>, stmt: &Statement<'tcx>, location: Loca
...
@@ -955,15 +970,15 @@ fn check_stmt(&mut self, mir: &Mir<'tcx>, stmt: &Statement<'tcx>, location: Loca
);
);
};
};
}
}
StatementKind
::
UserAssertTy
(
c_ty
,
local
)
=>
{
StatementKind
::
AscribeUserType
(
ref
place
,
c_ty
)
=>
{
let
local_ty
=
mir
.local_decls
()[
local
]
.ty
;
let
place_ty
=
place
.ty
(
mir
,
tcx
)
.to_ty
(
tcx
)
;
if
let
Err
(
terr
)
=
self
.
eq_canonical_type_and_type
(
c_ty
,
local
_ty
,
Locations
::
All
)
{
if
let
Err
(
terr
)
=
self
.
sub_type_and_user_type
(
place_ty
,
c
_ty
,
Locations
::
All
)
{
span_mirbug!
(
span_mirbug!
(
self
,
self
,
stmt
,
stmt
,
"bad type assert ({:?} = {:?}): {:?}"
,
"bad type assert ({:?} <: {:?}): {:?}"
,
place_ty
,
c_ty
,
c_ty
,
local_ty
,
terr
terr
);
);
}
}
...
...
src/librustc_mir/borrow_check/nll/type_check/relate_tys.rs
浏览文件 @
dd3cc966
...
@@ -22,6 +22,7 @@
...
@@ -22,6 +22,7 @@
use
rustc_data_structures
::
fx
::
FxHashMap
;
use
rustc_data_structures
::
fx
::
FxHashMap
;
use
rustc_data_structures
::
indexed_vec
::
IndexVec
;
use
rustc_data_structures
::
indexed_vec
::
IndexVec
;
/// Adds sufficient constraints to ensure that `a <: b`.
pub
(
super
)
fn
sub_types
<
'tcx
>
(
pub
(
super
)
fn
sub_types
<
'tcx
>
(
infcx
:
&
InferCtxt
<
'_
,
'_
,
'tcx
>
,
infcx
:
&
InferCtxt
<
'_
,
'_
,
'tcx
>
,
a
:
Ty
<
'tcx
>
,
a
:
Ty
<
'tcx
>
,
...
@@ -40,6 +41,7 @@ pub(super) fn sub_types<'tcx>(
...
@@ -40,6 +41,7 @@ pub(super) fn sub_types<'tcx>(
Ok
(())
Ok
(())
}
}
/// Adds sufficient constraints to ensure that `a == b`.
pub
(
super
)
fn
eq_types
<
'tcx
>
(
pub
(
super
)
fn
eq_types
<
'tcx
>
(
infcx
:
&
InferCtxt
<
'_
,
'_
,
'tcx
>
,
infcx
:
&
InferCtxt
<
'_
,
'_
,
'tcx
>
,
a
:
Ty
<
'tcx
>
,
a
:
Ty
<
'tcx
>
,
...
@@ -58,7 +60,43 @@ pub(super) fn eq_types<'tcx>(
...
@@ -58,7 +60,43 @@ pub(super) fn eq_types<'tcx>(
Ok
(())
Ok
(())
}
}
pub
(
super
)
fn
eq_canonical_type_and_type
<
'tcx
>
(
/// Adds sufficient constraints to ensure that `a <: b`, where `b` is
/// a user-given type (which means it may have canonical variables
/// encoding things like `_`).
pub
(
super
)
fn
sub_type_and_user_type
<
'tcx
>
(
infcx
:
&
InferCtxt
<
'_
,
'_
,
'tcx
>
,
a
:
Ty
<
'tcx
>
,
b
:
CanonicalTy
<
'tcx
>
,
locations
:
Locations
,
borrowck_context
:
Option
<&
mut
BorrowCheckContext
<
'_
,
'tcx
>>
,
)
->
Fallible
<
()
>
{
debug!
(
"sub_type_and_user_type(a={:?}, b={:?}, locations={:?})"
,
a
,
b
,
locations
);
let
Canonical
{
variables
:
b_variables
,
value
:
b_value
,
}
=
b
;
// (*) The `TypeRelating` code assumes that the "canonical variables"
// appear in the "a" side, so start with `Contravariant` ambient
// variance to get the right relationship.
TypeRelating
::
new
(
infcx
,
ty
::
Variance
::
Contravariant
,
// (*)
locations
,
borrowck_context
,
b_variables
,
)
.relate
(
&
b_value
,
&
a
)
?
;
Ok
(())
}
/// Adds sufficient constraints to ensure that `a <: b`, where `b` is
/// a user-given type (which means it may have canonical variables
/// encoding things like `_`).
pub
(
super
)
fn
eq_user_type_and_type
<
'tcx
>
(
infcx
:
&
InferCtxt
<
'_
,
'_
,
'tcx
>
,
infcx
:
&
InferCtxt
<
'_
,
'_
,
'tcx
>
,
a
:
CanonicalTy
<
'tcx
>
,
a
:
CanonicalTy
<
'tcx
>
,
b
:
Ty
<
'tcx
>
,
b
:
Ty
<
'tcx
>
,
...
@@ -66,16 +104,21 @@ pub(super) fn eq_canonical_type_and_type<'tcx>(
...
@@ -66,16 +104,21 @@ pub(super) fn eq_canonical_type_and_type<'tcx>(
borrowck_context
:
Option
<&
mut
BorrowCheckContext
<
'_
,
'tcx
>>
,
borrowck_context
:
Option
<&
mut
BorrowCheckContext
<
'_
,
'tcx
>>
,
)
->
Fallible
<
()
>
{
)
->
Fallible
<
()
>
{
debug!
(
debug!
(
"eq_
canonical
_type_and_type(a={:?}, b={:?}, locations={:?})"
,
"eq_
user
_type_and_type(a={:?}, b={:?}, locations={:?})"
,
a
,
b
,
locations
a
,
b
,
locations
);
);
let
Canonical
{
let
Canonical
{
variables
:
a_variables
,
variables
:
a_variables
,
value
:
a_value
,
value
:
a_value
,
}
=
a
;
}
=
a
;
// (*) The `TypeRelating` code assumes that the "canonical variables"
// appear in the "a" side, so start with `Contravariant` ambient
// variance to get the right relationship.
TypeRelating
::
new
(
TypeRelating
::
new
(
infcx
,
infcx
,
ty
::
Variance
::
Invariant
,
ty
::
Variance
::
Invariant
,
// (*)
locations
,
locations
,
borrowck_context
,
borrowck_context
,
a_variables
,
a_variables
,
...
...
src/librustc_mir/dataflow/impls/borrows.rs
浏览文件 @
dd3cc966
...
@@ -338,7 +338,7 @@ fn statement_effect(&self, sets: &mut BlockSets<BorrowIndex>, location: Location
...
@@ -338,7 +338,7 @@ fn statement_effect(&self, sets: &mut BlockSets<BorrowIndex>, location: Location
mir
::
StatementKind
::
SetDiscriminant
{
..
}
|
mir
::
StatementKind
::
SetDiscriminant
{
..
}
|
mir
::
StatementKind
::
StorageLive
(
..
)
|
mir
::
StatementKind
::
StorageLive
(
..
)
|
mir
::
StatementKind
::
Validate
(
..
)
|
mir
::
StatementKind
::
Validate
(
..
)
|
mir
::
StatementKind
::
UserAssertTy
(
..
)
|
mir
::
StatementKind
::
AscribeUserType
(
..
)
|
mir
::
StatementKind
::
Nop
=>
{}
mir
::
StatementKind
::
Nop
=>
{}
}
}
...
...
src/librustc_mir/dataflow/move_paths/builder.rs
浏览文件 @
dd3cc966
...
@@ -304,7 +304,7 @@ fn gather_statement(&mut self, stmt: &Statement<'tcx>) {
...
@@ -304,7 +304,7 @@ fn gather_statement(&mut self, stmt: &Statement<'tcx>) {
}
}
StatementKind
::
EndRegion
(
_
)
|
StatementKind
::
EndRegion
(
_
)
|
StatementKind
::
Validate
(
..
)
|
StatementKind
::
Validate
(
..
)
|
StatementKind
::
UserAssertTy
(
..
)
|
StatementKind
::
AscribeUserType
(
..
)
|
StatementKind
::
Nop
=>
{}
StatementKind
::
Nop
=>
{}
}
}
}
}
...
...
src/librustc_mir/interpret/step.rs
浏览文件 @
dd3cc966
...
@@ -159,7 +159,7 @@ fn statement(&mut self, stmt: &mir::Statement<'tcx>) -> EvalResult<'tcx> {
...
@@ -159,7 +159,7 @@ fn statement(&mut self, stmt: &mir::Statement<'tcx>) -> EvalResult<'tcx> {
}
}
EndRegion
(
..
)
=>
{}
EndRegion
(
..
)
=>
{}
UserAssertTy
(
..
)
=>
{}
AscribeUserType
(
..
)
=>
{}
// Defined to do nothing. These are added by optimization passes, to avoid changing the
// Defined to do nothing. These are added by optimization passes, to avoid changing the
// size of MIR constantly.
// size of MIR constantly.
...
...
src/librustc_mir/transform/check_unsafety.rs
浏览文件 @
dd3cc966
...
@@ -114,7 +114,7 @@ fn visit_statement(&mut self,
...
@@ -114,7 +114,7 @@ fn visit_statement(&mut self,
StatementKind
::
StorageDead
(
..
)
|
StatementKind
::
StorageDead
(
..
)
|
StatementKind
::
EndRegion
(
..
)
|
StatementKind
::
EndRegion
(
..
)
|
StatementKind
::
Validate
(
..
)
|
StatementKind
::
Validate
(
..
)
|
StatementKind
::
UserAssertTy
(
..
)
|
StatementKind
::
AscribeUserType
(
..
)
|
StatementKind
::
Nop
=>
{
StatementKind
::
Nop
=>
{
// safe (at least as emitted during MIR construction)
// safe (at least as emitted during MIR construction)
}
}
...
...
src/librustc_mir/transform/cleanup_post_borrowck.rs
浏览文件 @
dd3cc966
...
@@ -12,7 +12,7 @@
...
@@ -12,7 +12,7 @@
//!
//!
//! - `CleanEndRegions`, that reduces the set of `EndRegion` statements
//! - `CleanEndRegions`, that reduces the set of `EndRegion` statements
//! in the MIR.
//! in the MIR.
//! - `Clean
UserAssertTy`, that replaces all `UserAssertTy
` statements
//! - `Clean
AscribeUserType`, that replaces all `AscribeUserType
` statements
//! with `Nop`.
//! with `Nop`.
//!
//!
//! The `CleanEndRegions` "pass" is actually implemented as two
//! The `CleanEndRegions` "pass" is actually implemented as two
...
@@ -24,10 +24,10 @@
...
@@ -24,10 +24,10 @@
//! MIR and removes any `EndRegion` that is applied to a region that
//! MIR and removes any `EndRegion` that is applied to a region that
//! was not seen in the previous pass.
//! was not seen in the previous pass.
//!
//!
//! The `Clean
UserAssertTy
` pass runs at a distinct time from the
//! The `Clean
AscribeUserType
` pass runs at a distinct time from the
//! `CleanEndRegions` pass. It is important that the `Clean
UserAssertTy
`
//! `CleanEndRegions` pass. It is important that the `Clean
AscribeUserType
`
//! pass runs after the MIR borrowck so that the NLL type checker can
//! pass runs after the MIR borrowck so that the NLL type checker can
//! perform the type assertion when it encounters the `
UserAssertTy
`
//! perform the type assertion when it encounters the `
AscribeUserType
`
//! statements.
//! statements.
use
rustc_data_structures
::
fx
::
FxHashSet
;
use
rustc_data_structures
::
fx
::
FxHashSet
;
...
@@ -110,26 +110,26 @@ fn visit_statement(&mut self,
...
@@ -110,26 +110,26 @@ fn visit_statement(&mut self,
}
}
}
}
pub
struct
Clean
UserAssertTy
;
pub
struct
Clean
AscribeUserType
;
pub
struct
Delete
UserAssertTy
;
pub
struct
Delete
AscribeUserType
;
impl
MirPass
for
Clean
UserAssertTy
{
impl
MirPass
for
Clean
AscribeUserType
{
fn
run_pass
<
'a
,
'tcx
>
(
&
self
,
fn
run_pass
<
'a
,
'tcx
>
(
&
self
,
_
tcx
:
TyCtxt
<
'a
,
'tcx
,
'tcx
>
,
_
tcx
:
TyCtxt
<
'a
,
'tcx
,
'tcx
>
,
_
source
:
MirSource
,
_
source
:
MirSource
,
mir
:
&
mut
Mir
<
'tcx
>
)
{
mir
:
&
mut
Mir
<
'tcx
>
)
{
let
mut
delete
=
Delete
UserAssertTy
;
let
mut
delete
=
Delete
AscribeUserType
;
delete
.visit_mir
(
mir
);
delete
.visit_mir
(
mir
);
}
}
}
}
impl
<
'tcx
>
MutVisitor
<
'tcx
>
for
Delete
UserAssertTy
{
impl
<
'tcx
>
MutVisitor
<
'tcx
>
for
Delete
AscribeUserType
{
fn
visit_statement
(
&
mut
self
,
fn
visit_statement
(
&
mut
self
,
block
:
BasicBlock
,
block
:
BasicBlock
,
statement
:
&
mut
Statement
<
'tcx
>
,
statement
:
&
mut
Statement
<
'tcx
>
,
location
:
Location
)
{
location
:
Location
)
{
if
let
StatementKind
::
UserAssertTy
(
..
)
=
statement
.kind
{
if
let
StatementKind
::
AscribeUserType
(
..
)
=
statement
.kind
{
statement
.make_nop
();
statement
.make_nop
();
}
}
self
.super_statement
(
block
,
statement
,
location
);
self
.super_statement
(
block
,
statement
,
location
);
...
...
src/librustc_mir/transform/mod.rs
浏览文件 @
dd3cc966
...
@@ -238,8 +238,8 @@ fn optimized_mir<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx
...
@@ -238,8 +238,8 @@ fn optimized_mir<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx
simplify_branches
::
SimplifyBranches
::
new
(
"initial"
),
simplify_branches
::
SimplifyBranches
::
new
(
"initial"
),
remove_noop_landing_pads
::
RemoveNoopLandingPads
,
remove_noop_landing_pads
::
RemoveNoopLandingPads
,
simplify
::
SimplifyCfg
::
new
(
"early-opt"
),
simplify
::
SimplifyCfg
::
new
(
"early-opt"
),
// Remove all `
UserAssertTy
` statements.
// Remove all `
AscribeUserType
` statements.
cleanup_post_borrowck
::
Clean
UserAssertTy
,
cleanup_post_borrowck
::
Clean
AscribeUserType
,
// These next passes must be executed together
// These next passes must be executed together
add_call_guards
::
CriticalCallEdges
,
add_call_guards
::
CriticalCallEdges
,
...
...
src/librustc_mir/transform/qualify_consts.rs
浏览文件 @
dd3cc966
...
@@ -1098,7 +1098,7 @@ fn visit_statement(&mut self, bb: BasicBlock, statement: &Statement<'tcx>, locat
...
@@ -1098,7 +1098,7 @@ fn visit_statement(&mut self, bb: BasicBlock, statement: &Statement<'tcx>, locat
StatementKind
::
InlineAsm
{
..
}
|
StatementKind
::
InlineAsm
{
..
}
|
StatementKind
::
EndRegion
(
_
)
|
StatementKind
::
EndRegion
(
_
)
|
StatementKind
::
Validate
(
..
)
|
StatementKind
::
Validate
(
..
)
|
StatementKind
::
UserAssertTy
(
..
)
|
StatementKind
::
AscribeUserType
(
..
)
|
StatementKind
::
Nop
=>
{}
StatementKind
::
Nop
=>
{}
}
}
});
});
...
...
src/librustc_mir/transform/remove_noop_landing_pads.rs
浏览文件 @
dd3cc966
...
@@ -53,7 +53,7 @@ fn is_nop_landing_pad(
...
@@ -53,7 +53,7 @@ fn is_nop_landing_pad(
StatementKind
::
StorageLive
(
_
)
|
StatementKind
::
StorageLive
(
_
)
|
StatementKind
::
StorageDead
(
_
)
|
StatementKind
::
StorageDead
(
_
)
|
StatementKind
::
EndRegion
(
_
)
|
StatementKind
::
EndRegion
(
_
)
|
StatementKind
::
UserAssertTy
(
..
)
|
StatementKind
::
AscribeUserType
(
..
)
|
StatementKind
::
Nop
=>
{
StatementKind
::
Nop
=>
{
// These are all nops in a landing pad (there's some
// These are all nops in a landing pad (there's some
// borrowck interaction between EndRegion and storage
// borrowck interaction between EndRegion and storage
...
...
src/librustc_mir/transform/rustc_peek.rs
浏览文件 @
dd3cc966
...
@@ -163,7 +163,7 @@ fn each_block<'a, 'tcx, O>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
...
@@ -163,7 +163,7 @@ fn each_block<'a, 'tcx, O>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
mir
::
StatementKind
::
InlineAsm
{
..
}
|
mir
::
StatementKind
::
InlineAsm
{
..
}
|
mir
::
StatementKind
::
EndRegion
(
_
)
|
mir
::
StatementKind
::
EndRegion
(
_
)
|
mir
::
StatementKind
::
Validate
(
..
)
|
mir
::
StatementKind
::
Validate
(
..
)
|
mir
::
StatementKind
::
UserAssertTy
(
..
)
|
mir
::
StatementKind
::
AscribeUserType
(
..
)
|
mir
::
StatementKind
::
Nop
=>
continue
,
mir
::
StatementKind
::
Nop
=>
continue
,
mir
::
StatementKind
::
SetDiscriminant
{
..
}
=>
mir
::
StatementKind
::
SetDiscriminant
{
..
}
=>
span_bug!
(
stmt
.source_info.span
,
span_bug!
(
stmt
.source_info.span
,
...
...
src/librustc_passes/mir_stats.rs
浏览文件 @
dd3cc966
...
@@ -92,7 +92,7 @@ fn visit_statement(&mut self,
...
@@ -92,7 +92,7 @@ fn visit_statement(&mut self,
StatementKind
::
StorageLive
(
..
)
=>
"StatementKind::StorageLive"
,
StatementKind
::
StorageLive
(
..
)
=>
"StatementKind::StorageLive"
,
StatementKind
::
StorageDead
(
..
)
=>
"StatementKind::StorageDead"
,
StatementKind
::
StorageDead
(
..
)
=>
"StatementKind::StorageDead"
,
StatementKind
::
InlineAsm
{
..
}
=>
"StatementKind::InlineAsm"
,
StatementKind
::
InlineAsm
{
..
}
=>
"StatementKind::InlineAsm"
,
StatementKind
::
UserAssertTy
(
..
)
=>
"StatementKind::UserAssertTy
"
,
StatementKind
::
AscribeUserType
(
..
)
=>
"StatementKind::AscribeUserType
"
,
StatementKind
::
Nop
=>
"StatementKind::Nop"
,
StatementKind
::
Nop
=>
"StatementKind::Nop"
,
},
&
statement
.kind
);
},
&
statement
.kind
);
self
.super_statement
(
block
,
statement
,
location
);
self
.super_statement
(
block
,
statement
,
location
);
...
...
src/test/mir-opt/basic_assignment.rs
浏览文件 @
dd3cc966
...
@@ -48,7 +48,7 @@ fn main() {
...
@@ -48,7 +48,7 @@ fn main() {
// _2 = move _3;
// _2 = move _3;
// StorageDead(_3);
// StorageDead(_3);
// StorageLive(_4);
// StorageLive(_4);
//
UserAssertTy(Canonical { variables: [], value: std::option::Option<std::boxed::Box<u32>> }, _4
);
//
AscribeUserType(_4, Canonical { variables: [], value: std::option::Option<std::boxed::Box<u32>> }
);
// _4 = std::option::Option<std::boxed::Box<u32>>::None;
// _4 = std::option::Option<std::boxed::Box<u32>>::None;
// StorageLive(_5);
// StorageLive(_5);
// StorageLive(_6);
// StorageLive(_6);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录