Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
ac60db23
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,发现更多精彩内容 >>
提交
ac60db23
编写于
3月 09, 2022
作者:
B
b-naber
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
do use ty::Const in patterns and abstract consts
上级
b38077ea
变更
15
隐藏空白更改
内联
并排
Showing
15 changed file
with
105 addition
and
127 deletion
+105
-127
compiler/rustc_middle/src/thir.rs
compiler/rustc_middle/src/thir.rs
+8
-4
compiler/rustc_middle/src/thir/abstract_const.rs
compiler/rustc_middle/src/thir/abstract_const.rs
+1
-1
compiler/rustc_middle/src/thir/visit.rs
compiler/rustc_middle/src/thir/visit.rs
+0
-5
compiler/rustc_middle/src/ty/consts/kind.rs
compiler/rustc_middle/src/ty/consts/kind.rs
+6
-1
compiler/rustc_mir_build/src/build/matches/mod.rs
compiler/rustc_mir_build/src/build/matches/mod.rs
+2
-2
compiler/rustc_mir_build/src/build/matches/simplify.rs
compiler/rustc_mir_build/src/build/matches/simplify.rs
+3
-1
compiler/rustc_mir_build/src/build/matches/test.rs
compiler/rustc_mir_build/src/build/matches/test.rs
+8
-12
compiler/rustc_mir_build/src/build/misc.rs
compiler/rustc_mir_build/src/build/misc.rs
+6
-1
compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
+13
-17
compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs
compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs
+15
-24
compiler/rustc_mir_build/src/thir/pattern/mod.rs
compiler/rustc_mir_build/src/thir/pattern/mod.rs
+24
-34
compiler/rustc_mir_build/src/thir/pattern/usefulness.rs
compiler/rustc_mir_build/src/thir/pattern/usefulness.rs
+8
-5
compiler/rustc_privacy/src/lib.rs
compiler/rustc_privacy/src/lib.rs
+2
-6
compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
...ler/rustc_trait_selection/src/traits/const_evaluatable.rs
+8
-9
compiler/rustc_trait_selection/src/traits/object_safety.rs
compiler/rustc_trait_selection/src/traits/object_safety.rs
+1
-5
未找到文件。
compiler/rustc_middle/src/thir.rs
浏览文件 @
ac60db23
...
...
@@ -661,7 +661,7 @@ pub enum PatKind<'tcx> {
/// * Opaque constants, that must not be matched structurally. So anything that does not derive
/// `PartialEq` and `Eq`.
Constant
{
value
:
mir
::
ConstantKind
<
'tcx
>
,
value
:
ty
::
Const
<
'tcx
>
,
},
Range
(
PatRange
<
'tcx
>
),
...
...
@@ -691,8 +691,8 @@ pub enum PatKind<'tcx> {
#[derive(Copy,
Clone,
Debug,
PartialEq,
HashStable)]
pub
struct
PatRange
<
'tcx
>
{
pub
lo
:
mir
::
ConstantKind
<
'tcx
>
,
pub
hi
:
mir
::
ConstantKind
<
'tcx
>
,
pub
lo
:
ty
::
Const
<
'tcx
>
,
pub
hi
:
ty
::
Const
<
'tcx
>
,
pub
end
:
RangeEnd
,
}
...
...
@@ -736,7 +736,11 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
Some
(
adt_def
.variant
(
variant_index
))
}
_
=>
self
.ty
.ty_adt_def
()
.and_then
(|
adt
|
{
if
!
adt
.is_enum
()
{
Some
(
adt
.non_enum_variant
())
}
else
{
None
}
if
!
adt
.is_enum
()
{
Some
(
adt
.non_enum_variant
())
}
else
{
None
}
}),
};
...
...
compiler/rustc_middle/src/thir/abstract_const.rs
浏览文件 @
ac60db23
...
...
@@ -22,7 +22,7 @@ pub enum CastKind {
/// A node of an `AbstractConst`.
#[derive(Debug,
Clone,
Copy,
PartialEq,
Eq,
HashStable,
TyEncodable,
TyDecodable)]
pub
enum
Node
<
'tcx
>
{
Leaf
(
mir
::
ConstantKind
<
'tcx
>
),
Leaf
(
ty
::
Const
<
'tcx
>
),
Binop
(
mir
::
BinOp
,
NodeId
,
NodeId
),
UnaryOp
(
mir
::
UnOp
,
NodeId
),
FunctionCall
(
NodeId
,
&
'tcx
[
NodeId
]),
...
...
compiler/rustc_middle/src/thir/visit.rs
浏览文件 @
ac60db23
...
...
@@ -94,13 +94,8 @@ pub fn walk_expr<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, expr: &Exp
visitor
.visit_expr
(
&
visitor
.thir
()[
value
])
}
}
<<<<<<<
HEAD
ConstBlock
{
did
:
_
,
substs
:
_
}
=>
{}
Repeat
{
value
,
count
:
_
}
=>
{
=======
ConstBlock
{
value
}
=>
visitor
.visit_constant
(
value
),
Repeat
{
value
,
count
}
=>
{
>>>>>>>
6064
f16d846
(
change
thir
to
use
mir
::
ConstantKind
instead
of
ty
::
Const
)
visitor
.visit_expr
(
&
visitor
.thir
()[
value
]);
}
Array
{
ref
fields
}
|
Tuple
{
ref
fields
}
=>
{
...
...
compiler/rustc_middle/src/ty/consts/kind.rs
浏览文件 @
ac60db23
...
...
@@ -76,7 +76,11 @@ pub enum ConstKind<'tcx> {
impl
<
'tcx
>
ConstKind
<
'tcx
>
{
#[inline]
pub
fn
try_to_value
(
self
)
->
Option
<
ConstValue
<
'tcx
>>
{
if
let
ConstKind
::
Value
(
val
)
=
self
{
Some
(
val
)
}
else
{
None
}
if
let
ConstKind
::
Value
(
val
)
=
self
{
Some
(
val
)
}
else
{
None
}
}
#[inline]
...
...
@@ -126,6 +130,7 @@ pub fn eval(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Self {
#[inline]
/// Tries to evaluate the constant if it is `Unevaluated`. If that isn't possible or necessary
/// return `None`.
// FIXME(@lcnr): Completely rework the evaluation/normalization system for `ty::Const` once valtrees are merged.
pub
fn
try_eval
(
self
,
tcx
:
TyCtxt
<
'tcx
>
,
...
...
compiler/rustc_mir_build/src/build/matches/mod.rs
浏览文件 @
ac60db23
...
...
@@ -964,13 +964,13 @@ enum TestKind<'tcx> {
///
/// For `bool` we always generate two edges, one for `true` and one for
/// `false`.
options
:
FxIndexMap
<
ConstantKind
<
'tcx
>
,
u128
>
,
options
:
FxIndexMap
<
ty
::
Const
<
'tcx
>
,
u128
>
,
},
/// Test for equality with value, possibly after an unsizing coercion to
/// `ty`,
Eq
{
value
:
ConstantKind
<
'tcx
>
,
value
:
ty
::
Const
<
'tcx
>
,
// Integer types are handled by `SwitchInt`, and constants with ADT
// types are converted back into patterns, so this can only be `&str`,
// `&[T]`, `f32` or `f64`.
...
...
compiler/rustc_mir_build/src/build/matches/simplify.rs
浏览文件 @
ac60db23
...
...
@@ -228,7 +228,9 @@ fn simplify_match_pair<'pat>(
_
=>
(
None
,
0
),
};
if
let
Some
((
min
,
max
,
sz
))
=
range
{
if
let
(
Some
(
lo
),
Some
(
hi
))
=
(
lo
.try_to_bits
(
sz
),
hi
.try_to_bits
(
sz
))
{
if
let
(
Some
(
lo
),
Some
(
hi
))
=
(
lo
.val
()
.try_to_bits
(
sz
),
hi
.val
()
.try_to_bits
(
sz
))
{
// We want to compare ranges numerically, but the order of the bitwise
// representation of signed integers does not match their numeric order.
// Thus, to correct the ordering, we need to shift the range of signed
...
...
compiler/rustc_mir_build/src/build/matches/test.rs
浏览文件 @
ac60db23
...
...
@@ -86,7 +86,7 @@ pub(super) fn add_cases_to_switch<'pat>(
test_place
:
&
PlaceBuilder
<
'tcx
>
,
candidate
:
&
Candidate
<
'pat
,
'tcx
>
,
switch_ty
:
Ty
<
'tcx
>
,
options
:
&
mut
FxIndexMap
<
ConstantKind
<
'tcx
>
,
u128
>
,
options
:
&
mut
FxIndexMap
<
ty
::
Const
<
'tcx
>
,
u128
>
,
)
->
bool
{
let
Some
(
match_pair
)
=
candidate
.match_pairs
.iter
()
.find
(|
mp
|
mp
.place
==
*
test_place
)
else
{
return
false
;
...
...
@@ -264,7 +264,7 @@ pub(super) fn perform_test(
);
}
else
if
let
[
success
,
fail
]
=
*
make_target_blocks
(
self
)
{
assert_eq!
(
value
.ty
(),
ty
);
let
expect
=
self
.literal_operand
(
test
.span
,
value
);
let
expect
=
self
.literal_operand
(
test
.span
,
value
.into
()
);
let
val
=
Operand
::
Copy
(
place
);
self
.compare
(
block
,
success
,
fail
,
source_info
,
BinOp
::
Eq
,
expect
,
val
);
}
else
{
...
...
@@ -277,8 +277,8 @@ pub(super) fn perform_test(
let
target_blocks
=
make_target_blocks
(
self
);
// Test `val` by computing `lo <= val && val <= hi`, using primitive comparisons.
let
lo
=
self
.literal_operand
(
test
.span
,
lo
);
let
hi
=
self
.literal_operand
(
test
.span
,
hi
);
let
lo
=
self
.literal_operand
(
test
.span
,
lo
.into
()
);
let
hi
=
self
.literal_operand
(
test
.span
,
hi
.into
()
);
let
val
=
Operand
::
Copy
(
place
);
let
[
success
,
fail
]
=
*
target_blocks
else
{
...
...
@@ -366,11 +366,11 @@ fn non_scalar_compare(
block
:
BasicBlock
,
make_target_blocks
:
impl
FnOnce
(
&
mut
Self
)
->
Vec
<
BasicBlock
>
,
source_info
:
SourceInfo
,
value
:
ConstantKind
<
'tcx
>
,
value
:
ty
::
Const
<
'tcx
>
,
place
:
Place
<
'tcx
>
,
mut
ty
:
Ty
<
'tcx
>
,
)
{
let
mut
expect
=
self
.literal_operand
(
source_info
.span
,
value
);
let
mut
expect
=
self
.literal_operand
(
source_info
.span
,
value
.into
()
);
let
mut
val
=
Operand
::
Copy
(
place
);
// If we're using `b"..."` as a pattern, we need to insert an
...
...
@@ -760,11 +760,7 @@ fn error_simplifyable<'pat>(&mut self, match_pair: &MatchPair<'pat, 'tcx>) -> !
span_bug!
(
match_pair
.pattern.span
,
"simplifyable pattern found: {:?}"
,
match_pair
.pattern
)
}
fn
const_range_contains
(
&
self
,
range
:
PatRange
<
'tcx
>
,
value
:
ConstantKind
<
'tcx
>
,
)
->
Option
<
bool
>
{
fn
const_range_contains
(
&
self
,
range
:
PatRange
<
'tcx
>
,
value
:
ty
::
Const
<
'tcx
>
)
->
Option
<
bool
>
{
use
std
::
cmp
::
Ordering
::
*
;
let
tcx
=
self
.tcx
;
...
...
@@ -781,7 +777,7 @@ fn const_range_contains(
fn
values_not_contained_in_range
(
&
self
,
range
:
PatRange
<
'tcx
>
,
options
:
&
FxIndexMap
<
ConstantKind
<
'tcx
>
,
u128
>
,
options
:
&
FxIndexMap
<
ty
::
Const
<
'tcx
>
,
u128
>
,
)
->
Option
<
bool
>
{
for
&
val
in
options
.keys
()
{
if
self
.const_range_contains
(
range
,
val
)
?
{
...
...
compiler/rustc_mir_build/src/build/misc.rs
浏览文件 @
ac60db23
...
...
@@ -3,6 +3,7 @@
use
crate
::
build
::
Builder
;
use
rustc_middle
::
mir
;
use
rustc_middle
::
mir
::
*
;
use
rustc_middle
::
ty
::{
self
,
Ty
};
use
rustc_span
::{
Span
,
DUMMY_SP
};
...
...
@@ -25,7 +26,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
/// Convenience function for creating a literal operand, one
/// without any user type annotation.
crate
fn
literal_operand
(
&
mut
self
,
span
:
Span
,
literal
:
ConstantKind
<
'tcx
>
)
->
Operand
<
'tcx
>
{
crate
fn
literal_operand
(
&
mut
self
,
span
:
Span
,
literal
:
mir
::
ConstantKind
<
'tcx
>
,
)
->
Operand
<
'tcx
>
{
let
constant
=
Box
::
new
(
Constant
{
span
,
user_ty
:
None
,
literal
});
Operand
::
Constant
(
constant
)
}
...
...
compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
浏览文件 @
ac60db23
use
rustc_hir
as
hir
;
use
rustc_index
::
vec
::
Idx
;
use
rustc_infer
::
infer
::{
InferCtxt
,
TyCtxtInferExt
};
use
rustc_middle
::
mir
::
{
self
,
Field
}
;
use
rustc_middle
::
mir
::
Field
;
use
rustc_middle
::
thir
::{
FieldPat
,
Pat
,
PatKind
};
use
rustc_middle
::
ty
::
print
::
with_no_trimmed_paths
;
use
rustc_middle
::
ty
::{
self
,
AdtDef
,
Ty
,
TyCtxt
};
...
...
@@ -22,7 +22,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
#[instrument(level
=
"debug"
,
skip(self))]
pub
(
super
)
fn
const_to_pat
(
&
self
,
cv
:
mir
::
ConstantKind
<
'tcx
>
,
cv
:
ty
::
Const
<
'tcx
>
,
id
:
hir
::
HirId
,
span
:
Span
,
mir_structural_match_violation
:
bool
,
...
...
@@ -152,11 +152,7 @@ fn type_marked_structural(&self, ty: Ty<'tcx>) -> bool {
ty
.is_structural_eq_shallow
(
self
.infcx.tcx
)
}
fn
to_pat
(
&
mut
self
,
cv
:
mir
::
ConstantKind
<
'tcx
>
,
mir_structural_match_violation
:
bool
,
)
->
Pat
<
'tcx
>
{
fn
to_pat
(
&
mut
self
,
cv
:
ty
::
Const
<
'tcx
>
,
mir_structural_match_violation
:
bool
)
->
Pat
<
'tcx
>
{
trace!
(
self
.treat_byte_string_as_slice
);
// This method is just a wrapper handling a validity check; the heavy lifting is
// performed by the recursive `recur` method, which is not meant to be
...
...
@@ -250,7 +246,7 @@ fn type_may_have_partial_eq_impl(&self, ty: Ty<'tcx>) -> bool {
fn
field_pats
(
&
self
,
vals
:
impl
Iterator
<
Item
=
mir
::
ConstantKind
<
'tcx
>>
,
vals
:
impl
Iterator
<
Item
=
ty
::
Const
<
'tcx
>>
,
)
->
Result
<
Vec
<
FieldPat
<
'tcx
>>
,
FallbackToConstRef
>
{
vals
.enumerate
()
.map
(|(
idx
,
val
)|
{
...
...
@@ -263,7 +259,7 @@ fn field_pats(
// Recursive helper for `to_pat`; invoke that (instead of calling this directly).
fn
recur
(
&
self
,
cv
:
mir
::
ConstantKind
<
'tcx
>
,
cv
:
ty
::
Const
<
'tcx
>
,
mir_structural_match_violation
:
bool
,
)
->
Result
<
Pat
<
'tcx
>
,
FallbackToConstRef
>
{
let
id
=
self
.id
;
...
...
@@ -369,7 +365,7 @@ fn recur(
PatKind
::
Wild
}
ty
::
Adt
(
adt_def
,
substs
)
if
adt_def
.is_enum
()
=>
{
let
destructured
=
tcx
.destructure_
mir_constan
t
(
param_env
.and
(
cv
));
let
destructured
=
tcx
.destructure_
cons
t
(
param_env
.and
(
cv
));
PatKind
::
Variant
{
adt_def
:
*
adt_def
,
substs
,
...
...
@@ -380,12 +376,12 @@ fn recur(
}
}
ty
::
Tuple
(
_
)
|
ty
::
Adt
(
_
,
_
)
=>
{
let
destructured
=
tcx
.destructure_
mir_constan
t
(
param_env
.and
(
cv
));
let
destructured
=
tcx
.destructure_
cons
t
(
param_env
.and
(
cv
));
PatKind
::
Leaf
{
subpatterns
:
self
.field_pats
(
destructured
.fields
.iter
()
.copied
())
?
}
}
ty
::
Array
(
..
)
=>
PatKind
::
Array
{
prefix
:
tcx
.destructure_
mir_constan
t
(
param_env
.and
(
cv
))
.destructure_
cons
t
(
param_env
.and
(
cv
))
.fields
.iter
()
.map
(|
val
|
self
.recur
(
*
val
,
false
))
...
...
@@ -416,12 +412,12 @@ fn recur(
// arrays.
ty
::
Array
(
..
)
if
!
self
.treat_byte_string_as_slice
=>
{
let
old
=
self
.behind_reference
.replace
(
true
);
let
array
=
tcx
.deref_
mir_constan
t
(
self
.param_env
.and
(
cv
));
let
array
=
tcx
.deref_
cons
t
(
self
.param_env
.and
(
cv
));
let
val
=
PatKind
::
Deref
{
subpattern
:
Pat
{
kind
:
Box
::
new
(
PatKind
::
Array
{
prefix
:
tcx
.destructure_
mir_constan
t
(
param_env
.and
(
array
))
.destructure_
cons
t
(
param_env
.and
(
array
))
.fields
.iter
()
.map
(|
val
|
self
.recur
(
*
val
,
false
))
...
...
@@ -442,12 +438,12 @@ fn recur(
// pattern.
ty
::
Slice
(
elem_ty
)
=>
{
let
old
=
self
.behind_reference
.replace
(
true
);
let
array
=
tcx
.deref_
mir_constan
t
(
self
.param_env
.and
(
cv
));
let
array
=
tcx
.deref_
cons
t
(
self
.param_env
.and
(
cv
));
let
val
=
PatKind
::
Deref
{
subpattern
:
Pat
{
kind
:
Box
::
new
(
PatKind
::
Slice
{
prefix
:
tcx
.destructure_
mir_constan
t
(
param_env
.and
(
array
))
.destructure_
cons
t
(
param_env
.and
(
array
))
.fields
.iter
()
.map
(|
val
|
self
.recur
(
*
val
,
false
))
...
...
@@ -516,7 +512,7 @@ fn recur(
// we fall back to a const pattern. If we do not do this, we may end up with
// a !structural-match constant that is not of reference type, which makes it
// very hard to invoke `PartialEq::eq` on it as a fallback.
let
val
=
match
self
.recur
(
tcx
.deref_
mir_constan
t
(
self
.param_env
.and
(
cv
)),
false
)
{
let
val
=
match
self
.recur
(
tcx
.deref_
cons
t
(
self
.param_env
.and
(
cv
)),
false
)
{
Ok
(
subpattern
)
=>
PatKind
::
Deref
{
subpattern
},
Err
(
_
)
=>
PatKind
::
Constant
{
value
:
cv
},
};
...
...
compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs
浏览文件 @
ac60db23
...
...
@@ -52,7 +52,7 @@
use
rustc_index
::
vec
::
Idx
;
use
rustc_hir
::{
HirId
,
RangeEnd
};
use
rustc_middle
::
mir
::
{
self
,
Field
}
;
use
rustc_middle
::
mir
::
Field
;
use
rustc_middle
::
thir
::{
FieldPat
,
Pat
,
PatKind
,
PatRange
};
use
rustc_middle
::
ty
::
layout
::
IntegerExt
;
use
rustc_middle
::
ty
::{
self
,
Ty
,
TyCtxt
,
VariantDef
};
...
...
@@ -136,30 +136,20 @@ fn integral_size_and_signed_bias(tcx: TyCtxt<'_>, ty: Ty<'_>) -> Option<(Size, u
fn
from_const
<
'tcx
>
(
tcx
:
TyCtxt
<
'tcx
>
,
param_env
:
ty
::
ParamEnv
<
'tcx
>
,
value
:
mir
::
ConstantKind
<
'tcx
>
,
value
:
ty
::
Const
<
'tcx
>
,
)
->
Option
<
IntRange
>
{
let
ty
=
value
.ty
();
if
let
Some
((
target_size
,
bias
))
=
Self
::
integral_size_and_signed_bias
(
tcx
,
ty
)
{
let
val
=
(||
{
match
value
{
mir
::
ConstantKind
::
Val
(
ConstValue
::
Scalar
(
scalar
),
_
)
=>
{
// For this specific pattern we can skip a lot of effort and go
// straight to the result, after doing a bit of checking. (We
// could remove this branch and just fall through, which
// is more general but much slower.)
if
let
Ok
(
bits
)
=
scalar
.to_bits_or_ptr_internal
(
target_size
)
{
return
Some
(
bits
);
}
if
let
ty
::
ConstKind
::
Value
(
ConstValue
::
Scalar
(
scalar
))
=
value
.val
()
{
// For this specific pattern we can skip a lot of effort and go
// straight to the result, after doing a bit of checking. (We
// could remove this branch and just fall through, which
// is more general but much slower.)
if
let
Ok
(
bits
)
=
scalar
.to_bits_or_ptr_internal
(
target_size
)
{
return
Some
(
bits
);
}
mir
::
ConstantKind
::
Ty
(
c
)
=>
match
c
.val
()
{
ty
::
ConstKind
::
Value
(
_
)
=>
bug!
(
"encountered ConstValue in mir::ConstantKind::Ty, whereas this is expected to be in ConstantKind::Val"
),
_
=>
{}
},
_
=>
{}
}
// This is a more general form of the previous case.
value
.try_eval_bits
(
tcx
,
param_env
,
ty
)
})()
?
;
...
...
@@ -244,8 +234,8 @@ fn to_pat<'tcx>(&self, tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Pat<'tcx> {
let
(
lo
,
hi
)
=
(
lo
^
bias
,
hi
^
bias
);
let
env
=
ty
::
ParamEnv
::
empty
()
.and
(
ty
);
let
lo_const
=
mir
::
ConstantKind
::
from_bits
(
tcx
,
lo
,
env
);
let
hi_const
=
mir
::
ConstantKind
::
from_bits
(
tcx
,
hi
,
env
);
let
lo_const
=
ty
::
Const
::
from_bits
(
tcx
,
lo
,
env
);
let
hi_const
=
ty
::
Const
::
from_bits
(
tcx
,
hi
,
env
);
let
kind
=
if
lo
==
hi
{
PatKind
::
Constant
{
value
:
lo_const
}
...
...
@@ -640,9 +630,9 @@ pub(super) enum Constructor<'tcx> {
/// Ranges of integer literal values (`2`, `2..=5` or `2..5`).
IntRange
(
IntRange
),
/// Ranges of floating-point literal values (`2.0..=5.2`).
FloatRange
(
mir
::
ConstantKind
<
'tcx
>
,
mir
::
ConstantKind
<
'tcx
>
,
RangeEnd
),
FloatRange
(
ty
::
Const
<
'tcx
>
,
ty
::
Const
<
'tcx
>
,
RangeEnd
),
/// String literals. Strings are not quite the same as `&[u8]` so we treat them separately.
Str
(
mir
::
ConstantKind
<
'tcx
>
),
Str
(
ty
::
Const
<
'tcx
>
),
/// Array and slice patterns.
Slice
(
Slice
),
/// Constants that must not be matched structurally. They are treated as black
...
...
@@ -839,7 +829,8 @@ pub(super) fn is_covered_by<'p>(&self, pcx: PatCtxt<'_, 'p, 'tcx>, other: &Self)
}
}
(
Str
(
self_val
),
Str
(
other_val
))
=>
{
// FIXME: there's probably a more direct way of comparing for equality
// FIXME Once valtrees are available we can directly use the bytes
// in the `Str` variant of the valtree for the comparison here.
match
compare_const_vals
(
pcx
.cx.tcx
,
*
self_val
,
...
...
compiler/rustc_mir_build/src/thir/pattern/mod.rs
浏览文件 @
ac60db23
...
...
@@ -17,7 +17,7 @@
use
rustc_index
::
vec
::
Idx
;
use
rustc_middle
::
mir
::
interpret
::{
get_slice_bytes
,
ConstValue
};
use
rustc_middle
::
mir
::
interpret
::{
ErrorHandled
,
LitToConstError
,
LitToConstInput
};
use
rustc_middle
::
mir
::
{
self
,
UserTypeProjection
}
;
use
rustc_middle
::
mir
::
UserTypeProjection
;
use
rustc_middle
::
mir
::{
BorrowKind
,
Field
,
Mutability
};
use
rustc_middle
::
thir
::{
Ascription
,
BindingMode
,
FieldPat
,
Pat
,
PatKind
,
PatRange
,
PatTyProj
};
use
rustc_middle
::
ty
::
subst
::{
GenericArg
,
SubstsRef
};
...
...
@@ -121,8 +121,8 @@ fn lower_range_expr(
fn
lower_pattern_range
(
&
mut
self
,
ty
:
Ty
<
'tcx
>
,
lo
:
mir
::
ConstantKind
<
'tcx
>
,
hi
:
mir
::
ConstantKind
<
'tcx
>
,
lo
:
ty
::
Const
<
'tcx
>
,
hi
:
ty
::
Const
<
'tcx
>
,
end
:
RangeEnd
,
span
:
Span
,
)
->
PatKind
<
'tcx
>
{
...
...
@@ -177,24 +177,18 @@ fn normalize_range_pattern_ends(
ty
:
Ty
<
'tcx
>
,
lo
:
Option
<&
PatKind
<
'tcx
>>
,
hi
:
Option
<&
PatKind
<
'tcx
>>
,
)
->
Option
<
(
mir
::
ConstantKind
<
'tcx
>
,
mir
::
ConstantKind
<
'tcx
>
)
>
{
)
->
Option
<
(
ty
::
Const
<
'tcx
>
,
ty
::
Const
<
'tcx
>
)
>
{
match
(
lo
,
hi
)
{
(
Some
(
PatKind
::
Constant
{
value
:
lo
}),
Some
(
PatKind
::
Constant
{
value
:
hi
}))
=>
{
Some
((
*
lo
,
*
hi
))
}
(
Some
(
PatKind
::
Constant
{
value
:
lo
}),
None
)
=>
{
let
hi
=
ty
.numeric_max_val
(
self
.tcx
)
?
;
Some
((
*
lo
,
mir
::
ConstantKind
::
from_bits
(
self
.tcx
,
hi
,
ty
::
ParamEnv
::
empty
()
.and
(
ty
)),
))
Some
((
*
lo
,
ty
::
Const
::
from_bits
(
self
.tcx
,
hi
,
ty
::
ParamEnv
::
empty
()
.and
(
ty
))))
}
(
None
,
Some
(
PatKind
::
Constant
{
value
:
hi
}))
=>
{
let
lo
=
ty
.numeric_min_val
(
self
.tcx
)
?
;
Some
((
mir
::
ConstantKind
::
from_bits
(
self
.tcx
,
lo
,
ty
::
ParamEnv
::
empty
()
.and
(
ty
)),
*
hi
,
))
Some
((
ty
::
Const
::
from_bits
(
self
.tcx
,
lo
,
ty
::
ParamEnv
::
empty
()
.and
(
ty
)),
*
hi
))
}
_
=>
None
,
}
...
...
@@ -496,7 +490,7 @@ fn lower_path(&mut self, qpath: &hir::QPath<'_>, id: hir::HirId, span: Span) ->
match
self
.tcx
.const_eval_instance
(
param_env_reveal_all
,
instance
,
Some
(
span
))
{
Ok
(
value
)
=>
{
let
const_
=
mir
::
ConstantKind
::
Val
(
value
,
ty
);
let
const_
=
ty
::
Const
::
from_value
(
self
.tcx
,
value
,
ty
);
let
pattern
=
self
.const_to_pat
(
const_
,
id
,
span
,
mir_structural_match_violation
);
if
!
is_associated_const
{
...
...
@@ -545,30 +539,25 @@ fn lower_inline_const(
span
:
Span
,
)
->
PatKind
<
'tcx
>
{
let
anon_const_def_id
=
self
.tcx
.hir
()
.local_def_id
(
anon_const
.hir_id
);
let
value
=
mir
::
ConstantKind
::
from_inline_const
(
self
.tcx
,
anon_const_def_id
);
let
value
=
ty
::
Const
::
from_inline_const
(
self
.tcx
,
anon_const_def_id
);
// Evaluate early like we do in `lower_path`.
let
value
=
value
.eval
(
self
.tcx
,
self
.param_env
);
match
value
{
mir
::
ConstantKind
::
Ty
(
c
)
=>
{
match
c
.val
()
{
ConstKind
::
Param
(
_
)
=>
{
self
.errors
.push
(
PatternError
::
ConstParamInPattern
(
span
));
return
PatKind
::
Wild
;
}
ConstKind
::
Unevaluated
(
_
)
=>
{
// If we land here it means the const can't be evaluated because it's `TooGeneric`.
self
.tcx
.sess
.span_err
(
span
,
"constant pattern depends on a generic parameter"
);
return
PatKind
::
Wild
;
}
_
=>
bug!
(
"Expected either ConstKind::Param or ConstKind::Unevaluated"
),
}
match
value
.val
()
{
ConstKind
::
Param
(
_
)
=>
{
self
.errors
.push
(
PatternError
::
ConstParamInPattern
(
span
));
return
PatKind
::
Wild
;
}
mir
::
ConstantKind
::
Val
(
_
,
_
)
=>
*
self
.const_to_pat
(
value
,
id
,
span
,
false
)
.kind
,
ConstKind
::
Unevaluated
(
_
)
=>
{
// If we land here it means the const can't be evaluated because it's `TooGeneric`.
self
.tcx.sess
.span_err
(
span
,
"constant pattern depends on a generic parameter"
);
return
PatKind
::
Wild
;
}
_
=>
(),
}
*
self
.const_to_pat
(
value
,
id
,
span
,
false
)
.kind
}
/// Converts literals, paths and negation of literals to patterns.
...
...
@@ -595,7 +584,7 @@ fn lower_lit(&mut self, expr: &'tcx hir::Expr<'tcx>) -> PatKind<'tcx> {
let
lit_input
=
LitToConstInput
{
lit
:
&
lit
.node
,
ty
:
self
.typeck_results
.expr_ty
(
expr
),
neg
};
match
self
.tcx
.at
(
expr
.span
)
.lit_to_
mir_constan
t
(
lit_input
)
{
match
self
.tcx
.at
(
expr
.span
)
.lit_to_
cons
t
(
lit_input
)
{
Ok
(
constant
)
=>
*
self
.const_to_pat
(
constant
,
expr
.hir_id
,
lit
.span
,
false
)
.kind
,
Err
(
LitToConstError
::
Reported
)
=>
PatKind
::
Wild
,
Err
(
LitToConstError
::
TypeError
)
=>
bug!
(
"lower_lit: had type error"
),
...
...
@@ -750,11 +739,12 @@ fn super_fold_with<F: PatternFolder<'tcx>>(&self, folder: &mut F) -> Self {
}
}
// FIXME: Get rid of this function once valtrees land
#[instrument(skip(tcx),
level
=
"debug"
)]
crate
fn
compare_const_vals
<
'tcx
>
(
tcx
:
TyCtxt
<
'tcx
>
,
a
:
mir
::
ConstantKind
<
'tcx
>
,
b
:
mir
::
ConstantKind
<
'tcx
>
,
a
:
ty
::
Const
<
'tcx
>
,
b
:
ty
::
Const
<
'tcx
>
,
param_env
:
ty
::
ParamEnv
<
'tcx
>
,
ty
:
Ty
<
'tcx
>
,
)
->
Option
<
Ordering
>
{
...
...
compiler/rustc_mir_build/src/thir/pattern/usefulness.rs
浏览文件 @
ac60db23
...
...
@@ -765,10 +765,7 @@ fn lint_non_exhaustive_omitted_patterns<'p, 'tcx>(
/// `is_under_guard` is used to inform if the pattern has a guard. If it
/// has one it must not be inserted into the matrix. This shouldn't be
/// relied on for soundness.
#[instrument(
level
=
"debug"
,
skip(cx,
matrix,
witness_preference,
hir_id,
is_under_guard,
is_top_level)
)]
#[instrument(level
=
"debug"
,
skip(cx,
matrix,
hir_id))]
fn
is_useful
<
'p
,
'tcx
>
(
cx
:
&
MatchCheckCtxt
<
'p
,
'tcx
>
,
matrix
:
&
Matrix
<
'p
,
'tcx
>
,
...
...
@@ -800,6 +797,7 @@ fn is_useful<'p, 'tcx>(
let
ty
=
v
.head
()
.ty
();
let
is_non_exhaustive
=
cx
.is_foreign_non_exhaustive_enum
(
ty
);
debug!
(
"v.head: {:?}, v.span: {:?}"
,
v
.head
(),
v
.head
()
.span
());
let
pcx
=
PatCtxt
{
cx
,
ty
,
span
:
v
.head
()
.span
(),
is_top_level
,
is_non_exhaustive
};
// If the first pattern is an or-pattern, expand it.
...
...
@@ -809,9 +807,11 @@ fn is_useful<'p, 'tcx>(
// We try each or-pattern branch in turn.
let
mut
matrix
=
matrix
.clone
();
for
v
in
v
.expand_or_pat
()
{
debug!
(
?
v
);
let
usefulness
=
ensure_sufficient_stack
(||
{
is_useful
(
cx
,
&
matrix
,
&
v
,
witness_preference
,
hir_id
,
is_under_guard
,
false
)
});
debug!
(
?
usefulness
);
ret
.extend
(
usefulness
);
// If pattern has a guard don't add it to the matrix.
if
!
is_under_guard
{
...
...
@@ -822,6 +822,7 @@ fn is_useful<'p, 'tcx>(
}
}
else
{
let
v_ctor
=
v
.head
()
.ctor
();
debug!
(
?
v_ctor
);
if
let
Constructor
::
IntRange
(
ctor_range
)
=
&
v_ctor
{
// Lint on likely incorrect range patterns (#63987)
ctor_range
.lint_overlapping_range_endpoints
(
...
...
@@ -895,7 +896,7 @@ fn is_useful<'p, 'tcx>(
}
/// The arm of a match expression.
#[derive(Clone,
Copy)]
#[derive(Clone,
Copy
,
Debug
)]
crate
struct
MatchArm
<
'p
,
'tcx
>
{
/// The pattern must have been lowered through `check_match::MatchVisitor::lower_pattern`.
crate
pat
:
&
'p
DeconstructedPat
<
'p
,
'tcx
>
,
...
...
@@ -928,6 +929,7 @@ fn is_useful<'p, 'tcx>(
///
/// Note: the input patterns must have been lowered through
/// `check_match::MatchVisitor::lower_pattern`.
#[instrument(skip(cx,
arms),
level
=
"debug"
)]
crate
fn
compute_match_usefulness
<
'p
,
'tcx
>
(
cx
:
&
MatchCheckCtxt
<
'p
,
'tcx
>
,
arms
:
&
[
MatchArm
<
'p
,
'tcx
>
],
...
...
@@ -939,6 +941,7 @@ fn is_useful<'p, 'tcx>(
.iter
()
.copied
()
.map
(|
arm
|
{
debug!
(
?
arm
);
let
v
=
PatStack
::
from_pattern
(
arm
.pat
);
is_useful
(
cx
,
&
matrix
,
&
v
,
RealArm
,
arm
.hir_id
,
arm
.has_guard
,
true
);
if
!
arm
.has_guard
{
...
...
compiler/rustc_privacy/src/lib.rs
浏览文件 @
ac60db23
...
...
@@ -19,7 +19,6 @@
use
rustc_middle
::
bug
;
use
rustc_middle
::
hir
::
nested_filter
;
use
rustc_middle
::
middle
::
privacy
::{
AccessLevel
,
AccessLevels
};
use
rustc_middle
::
mir
::
ConstantKind
;
use
rustc_middle
::
span_bug
;
use
rustc_middle
::
thir
::
abstract_const
::
Node
as
ACNode
;
use
rustc_middle
::
ty
::
fold
::
TypeVisitor
;
...
...
@@ -157,10 +156,7 @@ fn visit_abstract_const_expr(
ct
:
AbstractConst
<
'tcx
>
,
)
->
ControlFlow
<
V
::
BreakTy
>
{
const_evaluatable
::
walk_abstract_const
(
tcx
,
ct
,
|
node
|
match
node
.root
(
tcx
)
{
ACNode
::
Leaf
(
leaf
)
=>
match
leaf
{
ConstantKind
::
Ty
(
c
)
=>
self
.visit_const
(
c
),
ConstantKind
::
Val
(
_
,
ty
)
=>
self
.visit_ty
(
ty
),
},
ACNode
::
Leaf
(
leaf
)
=>
self
.visit_const
(
leaf
),
ACNode
::
Cast
(
_
,
_
,
ty
)
=>
self
.visit_ty
(
ty
),
ACNode
::
Binop
(
..
)
|
ACNode
::
UnaryOp
(
..
)
|
ACNode
::
FunctionCall
(
_
,
_
)
=>
{
ControlFlow
::
CONTINUE
...
...
@@ -288,7 +284,7 @@ fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<V::BreakTy> {
fn
visit_const
(
&
mut
self
,
c
:
Const
<
'tcx
>
)
->
ControlFlow
<
Self
::
BreakTy
>
{
self
.visit_ty
(
c
.ty
())
?
;
let
tcx
=
self
.def_id_visitor
.tcx
();
if
let
Ok
(
Some
(
ct
))
=
AbstractConst
::
from_const
ant
(
tcx
,
ConstantKind
::
Ty
(
c
)
)
{
if
let
Ok
(
Some
(
ct
))
=
AbstractConst
::
from_const
(
tcx
,
c
)
{
self
.visit_abstract_const_expr
(
tcx
,
ct
)
?
;
}
ControlFlow
::
CONTINUE
...
...
compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
浏览文件 @
ac60db23
...
...
@@ -37,14 +37,9 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
param_env
:
ty
::
ParamEnv
<
'tcx
>
,
span
:
Span
,
)
->
Result
<
(),
NotConstEvaluatable
>
{
<<<<<<<
HEAD
let
tcx
=
infcx
.tcx
;
if
tcx
.features
()
.generic_const_exprs
{
=======
if
infcx
.tcx
.features
()
.generic_const_exprs
{
let
tcx
=
infcx
.tcx
;
>>>>>>>
6064
f16d846
(
change
thir
to
use
mir
::
ConstantKind
instead
of
ty
::
Const
)
match
AbstractConst
::
new
(
tcx
,
uv
)
?
{
// We are looking at a generic abstract constant.
Some
(
ct
)
=>
{
...
...
@@ -249,7 +244,7 @@ pub fn new(
Ok
(
inner
.map
(|
inner
|
AbstractConst
{
inner
,
substs
:
uv
.substs
}))
}
pub
fn
from_const
ant
(
pub
fn
from_const
(
tcx
:
TyCtxt
<
'tcx
>
,
ct
:
ty
::
Const
<
'tcx
>
,
)
->
Result
<
Option
<
AbstractConst
<
'tcx
>>
,
ErrorGuaranteed
>
{
...
...
@@ -382,6 +377,10 @@ fn visit_pat(&mut self, pat: &thir::Pat<'tcx>) {
}
}
fn
visit_const
(
&
mut
self
,
ct
:
ty
::
Const
<
'tcx
>
)
{
self
.is_poly
|
=
ct
.has_param_types_or_consts
();
}
fn
visit_constant
(
&
mut
self
,
ct
:
mir
::
ConstantKind
<
'tcx
>
)
{
self
.is_poly
|
=
ct
.has_param_types_or_consts
();
}
...
...
@@ -423,10 +422,10 @@ fn build(mut self) -> Result<&'tcx [Node<'tcx>], ErrorGuaranteed> {
self
.recurse_build
(
self
.body_id
)
?
;
for
n
in
self
.nodes
.iter
()
{
if
let
Node
::
Leaf
(
mir
::
ConstantKind
::
Ty
(
ty
::
Const
(
Interned
(
if
let
Node
::
Leaf
(
ty
::
Const
(
Interned
(
ty
::
ConstS
{
val
:
ty
::
ConstKind
::
Unevaluated
(
ct
),
ty
:
_
},
_
,
)))
)
=
n
)))
=
n
{
// `AbstractConst`s should not contain any promoteds as they require references which
// are not allowed.
...
...
@@ -863,4 +862,4 @@ fn try_unify(&self, a: AbstractConst<'tcx>, b: AbstractConst<'tcx>) -> bool {
false
>>>>>>> 6064f16d846 (change thir to use mir::ConstantKind instead of ty::Const)
*/
\ No newline at end of file
*/
compiler/rustc_trait_selection/src/traits/object_safety.rs
浏览文件 @
ac60db23
...
...
@@ -17,7 +17,6 @@
use
rustc_errors
::
FatalError
;
use
rustc_hir
as
hir
;
use
rustc_hir
::
def_id
::
DefId
;
use
rustc_middle
::
mir
::
ConstantKind
;
use
rustc_middle
::
ty
::
subst
::{
GenericArg
,
InternalSubsts
,
Subst
};
use
rustc_middle
::
ty
::{
self
,
Ty
,
TyCtxt
,
TypeFoldable
,
TypeVisitor
};
use
rustc_middle
::
ty
::{
Predicate
,
ToPredicate
};
...
...
@@ -837,10 +836,7 @@ fn visit_unevaluated_const(
if
let
Ok
(
Some
(
ct
))
=
AbstractConst
::
new
(
self
.tcx
,
uv
.shrink
())
{
const_evaluatable
::
walk_abstract_const
(
self
.tcx
,
ct
,
|
node
|
{
match
node
.root
(
self
.tcx
)
{
Node
::
Leaf
(
leaf
)
=>
match
leaf
{
ConstantKind
::
Ty
(
c
)
=>
self
.visit_const
(
c
),
ConstantKind
::
Val
(
_
,
ty
)
=>
self
.visit_ty
(
ty
),
},
Node
::
Leaf
(
leaf
)
=>
self
.visit_const
(
leaf
),
Node
::
Cast
(
_
,
_
,
ty
)
=>
self
.visit_ty
(
ty
),
Node
::
Binop
(
..
)
|
Node
::
UnaryOp
(
..
)
|
Node
::
FunctionCall
(
_
,
_
)
=>
{
ControlFlow
::
CONTINUE
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录