Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
e45c7955
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,发现更多精彩内容 >>
提交
e45c7955
编写于
4月 06, 2016
作者:
M
Masood Malekghassemi
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Replace consider_unification_despite_ambiguity with obligation variant
上级
57e5d43c
变更
19
隐藏空白更改
内联
并排
Showing
19 changed file
with
156 addition
and
75 deletion
+156
-75
src/librustc/diagnostics.rs
src/librustc/diagnostics.rs
+1
-0
src/librustc/middle/free_region.rs
src/librustc/middle/free_region.rs
+1
-0
src/librustc/traits/error_reporting.rs
src/librustc/traits/error_reporting.rs
+14
-0
src/librustc/traits/fulfill.rs
src/librustc/traits/fulfill.rs
+15
-0
src/librustc/traits/object_safety.rs
src/librustc/traits/object_safety.rs
+2
-0
src/librustc/traits/select.rs
src/librustc/traits/select.rs
+31
-74
src/librustc/traits/util.rs
src/librustc/traits/util.rs
+6
-0
src/librustc/ty/mod.rs
src/librustc/ty/mod.rs
+12
-1
src/librustc/ty/structural_impls.rs
src/librustc/ty/structural_impls.rs
+3
-0
src/librustc/ty/util.rs
src/librustc/ty/util.rs
+1
-0
src/librustc/ty/wf.rs
src/librustc/ty/wf.rs
+3
-0
src/librustc/util/ppaux.rs
src/librustc/util/ppaux.rs
+18
-0
src/librustc_metadata/tydecode.rs
src/librustc_metadata/tydecode.rs
+12
-0
src/librustc_metadata/tyencode.rs
src/librustc_metadata/tyencode.rs
+8
-0
src/librustc_typeck/check/closure.rs
src/librustc_typeck/check/closure.rs
+3
-0
src/librustc_typeck/check/method/probe.rs
src/librustc_typeck/check/method/probe.rs
+1
-0
src/librustc_typeck/collect.rs
src/librustc_typeck/collect.rs
+1
-0
src/librustdoc/clean/mod.rs
src/librustdoc/clean/mod.rs
+1
-0
src/test/compile-fail/closure-wrong-kind.rs
src/test/compile-fail/closure-wrong-kind.rs
+23
-0
未找到文件。
src/librustc/diagnostics.rs
浏览文件 @
e45c7955
...
...
@@ -1544,4 +1544,5 @@ fn cookie() -> ! { // error: definition of an unknown language item: `cookie`
E0490
,
// a value of type `..` is borrowed for too long
E0491
,
// in type `..`, reference has a longer lifetime than the data it...
E0495
,
// cannot infer an appropriate lifetime due to conflicting requirements
E0524
,
// the closure implements `..` but not `..`
}
src/librustc/middle/free_region.rs
浏览文件 @
e45c7955
...
...
@@ -59,6 +59,7 @@ pub fn relate_free_regions_from_predicates<'tcx>(&mut self,
ty
::
Predicate
::
Equate
(
..
)
|
ty
::
Predicate
::
WellFormed
(
..
)
|
ty
::
Predicate
::
ObjectSafe
(
..
)
|
ty
::
Predicate
::
ClosureKind
(
..
)
|
ty
::
Predicate
::
TypeOutlives
(
..
)
=>
{
// No region bounds here
}
...
...
src/librustc/traits/error_reporting.rs
浏览文件 @
e45c7955
...
...
@@ -466,6 +466,20 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
err
.emit
();
}
ty
::
Predicate
::
ClosureKind
(
closure_def_id
,
kind
)
=>
{
let
found_kind
=
infcx
.closure_kind
(
closure_def_id
)
.unwrap
();
let
closure_span
=
infcx
.tcx.map
.span_if_local
(
closure_def_id
)
.unwrap
();
let
mut
err
=
struct_span_err!
(
infcx
.tcx.sess
,
closure_span
,
E0524
,
"the closure implements `{}` but not `{}`"
,
found_kind
,
kind
);
err
.span_note
(
obligation
.cause.span
,
&
format!
(
"the requirement to implement `{}` derives from here"
,
kind
));
err
.emit
();
}
ty
::
Predicate
::
WellFormed
(
ty
)
=>
{
// WF predicates cannot themselves make
// errors. They can only block due to
...
...
src/librustc/traits/fulfill.rs
浏览文件 @
e45c7955
...
...
@@ -652,6 +652,21 @@ fn process_predicate1<'a,'tcx>(selcx: &mut SelectionContext<'a,'tcx>,
}
}
ty
::
Predicate
::
ClosureKind
(
closure_def_id
,
kind
)
=>
{
match
selcx
.infcx
()
.closure_kind
(
closure_def_id
)
{
Some
(
closure_kind
)
=>
{
if
closure_kind
.extends
(
kind
)
{
Ok
(
Some
(
vec!
[]))
}
else
{
Err
(
CodeSelectionError
(
Unimplemented
))
}
}
None
=>
{
Ok
(
None
)
}
}
}
ty
::
Predicate
::
WellFormed
(
ty
)
=>
{
match
ty
::
wf
::
obligations
(
selcx
.infcx
(),
obligation
.cause.body_id
,
ty
,
obligation
.cause.span
)
{
...
...
src/librustc/traits/object_safety.rs
浏览文件 @
e45c7955
...
...
@@ -165,6 +165,7 @@ pub fn supertraits_reference_self<'tcx>(tcx: &TyCtxt<'tcx>,
ty
::
Predicate
::
ObjectSafe
(
..
)
|
ty
::
Predicate
::
TypeOutlives
(
..
)
|
ty
::
Predicate
::
RegionOutlives
(
..
)
|
ty
::
Predicate
::
ClosureKind
(
..
)
|
ty
::
Predicate
::
Equate
(
..
)
=>
{
false
}
...
...
@@ -207,6 +208,7 @@ fn generics_require_sized_self<'tcx>(tcx: &TyCtxt<'tcx>,
ty
::
Predicate
::
RegionOutlives
(
..
)
|
ty
::
Predicate
::
WellFormed
(
..
)
|
ty
::
Predicate
::
ObjectSafe
(
..
)
|
ty
::
Predicate
::
ClosureKind
(
..
)
|
ty
::
Predicate
::
TypeOutlives
(
..
)
=>
{
false
}
...
...
src/librustc/traits/select.rs
浏览文件 @
e45c7955
...
...
@@ -198,9 +198,10 @@ enum SelectionCandidate<'tcx> {
/// we found an applicable bound in the trait definition.
ProjectionCandidate
,
/// Implementation of a `Fn`-family trait by one of the
/// anonymous types generated for a `||` expression.
ClosureCandidate
(
/* closure */
DefId
,
&
'tcx
ty
::
ClosureSubsts
<
'tcx
>
),
/// Implementation of a `Fn`-family trait by one of the anonymous types
/// generated for a `||` expression. The ty::ClosureKind informs the
/// confirmation step what ClosureKind obligation to emit.
ClosureCandidate
(
/* closure */
DefId
,
&
'tcx
ty
::
ClosureSubsts
<
'tcx
>
,
ty
::
ClosureKind
),
/// Implementation of a `Fn`-family trait by one of the anonymous
/// types generated for a fn pointer type (e.g., `fn(int)->int`)
...
...
@@ -321,75 +322,11 @@ pub fn select(&mut self, obligation: &TraitObligation<'tcx>)
let
stack
=
self
.push_stack
(
TraitObligationStackList
::
empty
(),
obligation
);
match
self
.candidate_from_obligation
(
&
stack
)
?
{
None
=>
{
self
.consider_unification_despite_ambiguity
(
obligation
);
Ok
(
None
)
}
None
=>
Ok
(
None
),
Some
(
candidate
)
=>
Ok
(
Some
(
self
.confirm_candidate
(
obligation
,
candidate
)
?
)),
}
}
/// In the particular case of unboxed closure obligations, we can
/// sometimes do some amount of unification for the
/// argument/return types even though we can't yet fully match obligation.
/// The particular case we are interesting in is an obligation of the form:
///
/// C : FnFoo<A>
///
/// where `C` is an unboxed closure type and `FnFoo` is one of the
/// `Fn` traits. Because we know that users cannot write impls for closure types
/// themselves, the only way that `C : FnFoo` can fail to match is under two
/// conditions:
///
/// 1. The closure kind for `C` is not yet known, because inference isn't complete.
/// 2. The closure kind for `C` *is* known, but doesn't match what is needed.
/// For example, `C` may be a `FnOnce` closure, but a `Fn` closure is needed.
///
/// In either case, we always know what argument types are
/// expected by `C`, no matter what kind of `Fn` trait it
/// eventually matches. So we can go ahead and unify the argument
/// types, even though the end result is ambiguous.
///
/// Note that this is safe *even if* the trait would never be
/// matched (case 2 above). After all, in that case, an error will
/// result, so it kind of doesn't matter what we do --- unifying
/// the argument types can only be helpful to the user, because
/// once they patch up the kind of closure that is expected, the
/// argment types won't really change.
fn
consider_unification_despite_ambiguity
(
&
mut
self
,
obligation
:
&
TraitObligation
<
'tcx
>
)
{
// Is this a `C : FnFoo(...)` trait reference for some trait binding `FnFoo`?
match
self
.tcx
()
.lang_items
.fn_trait_kind
(
obligation
.predicate
.0
.def_id
())
{
Some
(
_
)
=>
{
}
None
=>
{
return
;
}
}
// Is the self-type a closure type? We ignore bindings here
// because if it is a closure type, it must be a closure type from
// within this current fn, and hence none of the higher-ranked
// lifetimes can appear inside the self-type.
let
self_ty
=
self
.infcx
.shallow_resolve
(
*
obligation
.self_ty
()
.skip_binder
());
let
(
closure_def_id
,
substs
)
=
match
self_ty
.sty
{
ty
::
TyClosure
(
id
,
ref
substs
)
=>
(
id
,
substs
),
_
=>
{
return
;
}
};
assert
!
(
!
substs
.has_escaping_regions
());
// It is OK to call the unnormalized variant here - this is only
// reached for TyClosure: Fn inputs where the closure kind is
// still unknown, which should only occur in typeck where the
// closure type is already normalized.
let
closure_trait_ref
=
self
.closure_trait_ref_unnormalized
(
obligation
,
closure_def_id
,
substs
);
match
self
.confirm_poly_trait_refs
(
obligation
.cause
.clone
(),
obligation
.predicate
.to_poly_trait_ref
(),
closure_trait_ref
)
{
Ok
(())
=>
{
}
Err
(
_
)
=>
{
/* Silently ignore errors. */
}
}
}
///////////////////////////////////////////////////////////////////////////
// EVALUATION
//
...
...
@@ -532,6 +469,21 @@ fn evaluate_predicate_recursively<'o>(&mut self,
}
}
}
ty
::
Predicate
::
ClosureKind
(
closure_def_id
,
kind
)
=>
{
match
self
.infcx
.closure_kind
(
closure_def_id
)
{
Some
(
closure_kind
)
=>
{
if
closure_kind
.extends
(
kind
)
{
EvaluatedToOk
}
else
{
EvaluatedToErr
}
}
None
=>
{
EvaluatedToAmbig
}
}
}
}
}
...
...
@@ -1282,12 +1234,12 @@ fn assemble_closure_candidates(&mut self,
Some
(
closure_kind
)
=>
{
debug!
(
"assemble_unboxed_candidates: closure_kind = {:?}"
,
closure_kind
);
if
closure_kind
.extends
(
kind
)
{
candidates
.vec
.push
(
ClosureCandidate
(
closure_def_id
,
substs
));
candidates
.vec
.push
(
ClosureCandidate
(
closure_def_id
,
substs
,
kind
));
}
}
None
=>
{
debug!
(
"assemble_unboxed_candidates: closure_kind not yet known"
);
candidates
.
ambiguous
=
true
;
candidates
.
vec
.push
(
ClosureCandidate
(
closure_def_id
,
substs
,
kind
))
;
}
}
...
...
@@ -2071,9 +2023,9 @@ fn confirm_candidate(&mut self,
Ok
(
VtableImpl
(
vtable_impl
))
}
ClosureCandidate
(
closure_def_id
,
substs
)
=>
{
ClosureCandidate
(
closure_def_id
,
substs
,
kind
)
=>
{
let
vtable_closure
=
self
.confirm_closure_candidate
(
obligation
,
closure_def_id
,
substs
)
?
;
self
.confirm_closure_candidate
(
obligation
,
closure_def_id
,
substs
,
kind
)
?
;
Ok
(
VtableClosure
(
vtable_closure
))
}
...
...
@@ -2430,7 +2382,8 @@ fn confirm_fn_pointer_candidate(&mut self,
fn
confirm_closure_candidate
(
&
mut
self
,
obligation
:
&
TraitObligation
<
'tcx
>
,
closure_def_id
:
DefId
,
substs
:
&
ty
::
ClosureSubsts
<
'tcx
>
)
substs
:
&
ty
::
ClosureSubsts
<
'tcx
>
,
kind
:
ty
::
ClosureKind
)
->
Result
<
VtableClosureData
<
'tcx
,
PredicateObligation
<
'tcx
>>
,
SelectionError
<
'tcx
>>
{
...
...
@@ -2441,7 +2394,7 @@ fn confirm_closure_candidate(&mut self,
let
Normalized
{
value
:
trait_ref
,
obligations
mut
obligations
}
=
self
.closure_trait_ref
(
obligation
,
closure_def_id
,
substs
);
debug!
(
"confirm_closure_candidate(closure_def_id={:?}, trait_ref={:?}, obligations={:?})"
,
...
...
@@ -2453,6 +2406,10 @@ fn confirm_closure_candidate(&mut self,
obligation
.predicate
.to_poly_trait_ref
(),
trait_ref
)
?
;
obligations
.push
(
Obligation
::
new
(
obligation
.cause
.clone
(),
ty
::
Predicate
::
ClosureKind
(
closure_def_id
,
kind
)));
Ok
(
VtableClosureData
{
closure_def_id
:
closure_def_id
,
substs
:
substs
.clone
(),
...
...
src/librustc/traits/util.rs
浏览文件 @
e45c7955
...
...
@@ -60,6 +60,9 @@ fn insert(&mut self, pred: &ty::Predicate<'tcx>) -> bool {
ty
::
Predicate
::
ObjectSafe
(
data
)
=>
ty
::
Predicate
::
ObjectSafe
(
data
),
ty
::
Predicate
::
ClosureKind
(
closure_def_id
,
kind
)
=>
ty
::
Predicate
::
ClosureKind
(
closure_def_id
,
kind
)
};
self
.set
.insert
(
normalized_pred
)
}
...
...
@@ -156,6 +159,9 @@ fn push(&mut self, predicate: &ty::Predicate<'tcx>) {
ty
::
Predicate
::
Projection
(
..
)
=>
{
// Nothing to elaborate in a projection predicate.
}
ty
::
Predicate
::
ClosureKind
(
..
)
=>
{
// Nothing to elaborate when waiting for a closure's kind to be inferred.
}
ty
::
Predicate
::
RegionOutlives
(
..
)
|
ty
::
Predicate
::
TypeOutlives
(
..
)
=>
{
// Currently, we do not "elaborate" predicates like
...
...
src/librustc/ty/mod.rs
浏览文件 @
e45c7955
...
...
@@ -784,6 +784,11 @@ pub enum Predicate<'tcx> {
/// trait must be object-safe
ObjectSafe
(
DefId
),
/// No direct syntax. May be thought of as `where T : FnFoo<...>` for some 'TypeSpace'
/// substitutions `...` and T being a closure type. Satisfied (or refuted) once we know the
/// closure's kind.
ClosureKind
(
DefId
,
ClosureKind
),
}
impl
<
'tcx
>
Predicate
<
'tcx
>
{
...
...
@@ -873,6 +878,8 @@ pub fn subst_supertrait(&self,
Predicate
::
WellFormed
(
data
.subst
(
tcx
,
substs
)),
Predicate
::
ObjectSafe
(
trait_def_id
)
=>
Predicate
::
ObjectSafe
(
trait_def_id
),
Predicate
::
ClosureKind
(
closure_def_id
,
kind
)
=>
Predicate
::
ClosureKind
(
closure_def_id
,
kind
),
}
}
}
...
...
@@ -1060,6 +1067,9 @@ pub fn walk_tys(&self) -> IntoIter<Ty<'tcx>> {
ty
::
Predicate
::
ObjectSafe
(
_
trait_def_id
)
=>
{
vec!
[]
}
ty
::
Predicate
::
ClosureKind
(
_
closure_def_id
,
_
kind
)
=>
{
vec!
[]
}
};
// The only reason to collect into a vector here is that I was
...
...
@@ -1080,6 +1090,7 @@ pub fn to_opt_poly_trait_ref(&self) -> Option<PolyTraitRef<'tcx>> {
Predicate
::
RegionOutlives
(
..
)
|
Predicate
::
WellFormed
(
..
)
|
Predicate
::
ObjectSafe
(
..
)
|
Predicate
::
ClosureKind
(
..
)
|
Predicate
::
TypeOutlives
(
..
)
=>
{
None
}
...
...
@@ -1735,7 +1746,7 @@ pub struct ItemSubsts<'tcx> {
pub
substs
:
Substs
<
'tcx
>
,
}
#[derive(Clone,
Copy,
PartialOrd,
Ord,
PartialEq,
Eq,
Debug,
RustcEncodable,
RustcDecodable)]
#[derive(Clone,
Copy,
PartialOrd,
Ord,
PartialEq,
Eq,
Hash,
Debug,
RustcEncodable,
RustcDecodable)]
pub
enum
ClosureKind
{
// Warning: Ordering is significant here! The ordering is chosen
// because the trait Fn is a subtrait of FnMut and so in turn, and
...
...
src/librustc/ty/structural_impls.rs
浏览文件 @
e45c7955
...
...
@@ -644,6 +644,8 @@ fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
ty
::
Predicate
::
Projection
(
binder
.fold_with
(
folder
)),
ty
::
Predicate
::
WellFormed
(
data
)
=>
ty
::
Predicate
::
WellFormed
(
data
.fold_with
(
folder
)),
ty
::
Predicate
::
ClosureKind
(
closure_def_id
,
kind
)
=>
ty
::
Predicate
::
ClosureKind
(
closure_def_id
,
kind
),
ty
::
Predicate
::
ObjectSafe
(
trait_def_id
)
=>
ty
::
Predicate
::
ObjectSafe
(
trait_def_id
),
}
...
...
@@ -657,6 +659,7 @@ fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
ty
::
Predicate
::
TypeOutlives
(
ref
binder
)
=>
binder
.visit_with
(
visitor
),
ty
::
Predicate
::
Projection
(
ref
binder
)
=>
binder
.visit_with
(
visitor
),
ty
::
Predicate
::
WellFormed
(
data
)
=>
data
.visit_with
(
visitor
),
ty
::
Predicate
::
ClosureKind
(
_
closure_def_id
,
_
kind
)
=>
false
,
ty
::
Predicate
::
ObjectSafe
(
_
trait_def_id
)
=>
false
,
}
}
...
...
src/librustc/ty/util.rs
浏览文件 @
e45c7955
...
...
@@ -301,6 +301,7 @@ pub fn required_region_bounds(&self,
ty
::
Predicate
::
Equate
(
..
)
|
ty
::
Predicate
::
WellFormed
(
..
)
|
ty
::
Predicate
::
ObjectSafe
(
..
)
|
ty
::
Predicate
::
ClosureKind
(
..
)
|
ty
::
Predicate
::
RegionOutlives
(
..
)
=>
{
None
}
...
...
src/librustc/ty/wf.rs
浏览文件 @
e45c7955
...
...
@@ -92,6 +92,8 @@ pub fn predicate_obligations<'a,'tcx>(infcx: &InferCtxt<'a, 'tcx>,
}
ty
::
Predicate
::
ObjectSafe
(
_
)
=>
{
}
ty
::
Predicate
::
ClosureKind
(
..
)
=>
{
}
}
wf
.normalize
()
...
...
@@ -155,6 +157,7 @@ pub fn implied_bounds<'a,'tcx>(
ty
::
Predicate
::
Trait
(
..
)
|
ty
::
Predicate
::
Equate
(
..
)
|
ty
::
Predicate
::
Projection
(
..
)
|
ty
::
Predicate
::
ClosureKind
(
..
)
|
ty
::
Predicate
::
ObjectSafe
(
..
)
=>
vec!
[],
...
...
src/librustc/util/ppaux.rs
浏览文件 @
e45c7955
...
...
@@ -453,6 +453,9 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
ty
::
Predicate
::
ObjectSafe
(
trait_def_id
)
=>
{
write!
(
f
,
"ObjectSafe({:?})"
,
trait_def_id
)
}
ty
::
Predicate
::
ClosureKind
(
closure_def_id
,
kind
)
=>
{
write!
(
f
,
"ClosureKind({:?}, {:?})"
,
closure_def_id
,
kind
)
}
}
}
}
...
...
@@ -1027,6 +1030,16 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
}
}
impl
fmt
::
Display
for
ty
::
ClosureKind
{
fn
fmt
(
&
self
,
f
:
&
mut
fmt
::
Formatter
)
->
fmt
::
Result
{
match
*
self
{
ty
::
ClosureKind
::
Fn
=>
write!
(
f
,
"Fn"
),
ty
::
ClosureKind
::
FnMut
=>
write!
(
f
,
"FnMut"
),
ty
::
ClosureKind
::
FnOnce
=>
write!
(
f
,
"FnOnce"
),
}
}
}
impl
<
'tcx
>
fmt
::
Display
for
ty
::
Predicate
<
'tcx
>
{
fn
fmt
(
&
self
,
f
:
&
mut
fmt
::
Formatter
)
->
fmt
::
Result
{
match
*
self
{
...
...
@@ -1040,6 +1053,11 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
ty
::
tls
::
with
(|
tcx
|
{
write!
(
f
,
"the trait `{}` is object-safe"
,
tcx
.item_path_str
(
trait_def_id
))
}),
ty
::
Predicate
::
ClosureKind
(
closure_def_id
,
kind
)
=>
ty
::
tls
::
with
(|
tcx
|
{
write!
(
f
,
"the closure `{}` implements the trait `{}`"
,
tcx
.item_path_str
(
closure_def_id
),
kind
)
}),
}
}
}
src/librustc_metadata/tydecode.rs
浏览文件 @
e45c7955
...
...
@@ -553,6 +553,18 @@ pub fn parse_predicate(&mut self) -> ty::Predicate<'tcx> {
assert_eq!
(
self
.next
(),
'|'
);
ty
::
Predicate
::
ObjectSafe
(
def_id
)
}
'c'
=>
{
let
def_id
=
self
.parse_def
();
assert_eq!
(
self
.next
(),
'|'
);
let
kind
=
match
self
.next
()
{
'f'
=>
ty
::
ClosureKind
::
Fn
,
'm'
=>
ty
::
ClosureKind
::
FnMut
,
'o'
=>
ty
::
ClosureKind
::
FnOnce
,
c
=>
bug!
(
"Encountered invalid character in metadata: {}"
,
c
)
};
assert_eq!
(
self
.next
(),
'|'
);
ty
::
Predicate
::
ClosureKind
(
def_id
,
kind
)
}
c
=>
bug!
(
"Encountered invalid character in metadata: {}"
,
c
)
}
}
...
...
src/librustc_metadata/tyencode.rs
浏览文件 @
e45c7955
...
...
@@ -479,6 +479,14 @@ pub fn enc_predicate<'a, 'tcx>(w: &mut Cursor<Vec<u8>>,
ty
::
Predicate
::
ObjectSafe
(
trait_def_id
)
=>
{
write!
(
w
,
"O{}|"
,
(
cx
.ds
)(
cx
.tcx
,
trait_def_id
));
}
ty
::
Predicate
::
ClosureKind
(
closure_def_id
,
kind
)
=>
{
let
kind_char
=
match
kind
{
ty
::
ClosureKind
::
Fn
=>
'f'
,
ty
::
ClosureKind
::
FnMut
=>
'm'
,
ty
::
ClosureKind
::
FnOnce
=>
'o'
,
};
write!
(
w
,
"c{}|{}|"
,
(
cx
.ds
)(
cx
.tcx
,
closure_def_id
),
kind_char
);
}
}
}
...
...
src/librustc_typeck/check/closure.rs
浏览文件 @
e45c7955
...
...
@@ -179,6 +179,9 @@ fn deduce_expectations_from_obligations<'a,'tcx>(
ty
::
Predicate
::
TypeOutlives
(
..
)
=>
None
,
ty
::
Predicate
::
WellFormed
(
..
)
=>
None
,
ty
::
Predicate
::
ObjectSafe
(
..
)
=>
None
,
ty
::
Predicate
::
ClosureKind
(
_
closure_def_id
,
kind
)
=>
{
return
Some
(
kind
);
}
};
opt_trait_ref
.and_then
(|
trait_ref
|
self_type_matches_expected_vid
(
fcx
,
trait_ref
,
expected_vid
))
...
...
src/librustc_typeck/check/method/probe.rs
浏览文件 @
e45c7955
...
...
@@ -491,6 +491,7 @@ fn assemble_inherent_candidates_from_param(&mut self,
ty
::
Predicate
::
RegionOutlives
(
..
)
|
ty
::
Predicate
::
WellFormed
(
..
)
|
ty
::
Predicate
::
ObjectSafe
(
..
)
|
ty
::
Predicate
::
ClosureKind
(
..
)
|
ty
::
Predicate
::
TypeOutlives
(
..
)
=>
{
None
}
...
...
src/librustc_typeck/collect.rs
浏览文件 @
e45c7955
...
...
@@ -449,6 +449,7 @@ fn get_type_parameter_bounds(&self,
ty
::
Predicate
::
RegionOutlives
(
..
)
|
ty
::
Predicate
::
WellFormed
(
..
)
|
ty
::
Predicate
::
ObjectSafe
(
..
)
|
ty
::
Predicate
::
ClosureKind
(
..
)
|
ty
::
Predicate
::
Projection
(
..
)
=>
{
false
}
...
...
src/librustdoc/clean/mod.rs
浏览文件 @
e45c7955
...
...
@@ -853,6 +853,7 @@ fn clean(&self, cx: &DocContext) -> WherePredicate {
Predicate
::
Projection
(
ref
pred
)
=>
pred
.clean
(
cx
),
Predicate
::
WellFormed
(
_
)
=>
panic!
(
"not user writable"
),
Predicate
::
ObjectSafe
(
_
)
=>
panic!
(
"not user writable"
),
Predicate
::
ClosureKind
(
..
)
=>
panic!
(
"not user writable"
),
}
}
}
...
...
src/test/compile-fail/closure-wrong-kind.rs
0 → 100644
浏览文件 @
e45c7955
// Copyright 2016 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.
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
struct
X
;
fn
foo
<
T
>
(
_
:
T
)
{}
fn
bar
<
T
:
Fn
(
u32
)
>
(
_
:
T
)
{}
fn
main
()
{
let
x
=
X
;
let
closure
=
|
_
|
foo
(
x
);
//~^ ERROR the closure implements `FnOnce` but not `Fn`
bar
(
closure
);
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录