Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
98525aee
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,发现更多精彩内容 >>
提交
98525aee
编写于
2月 22, 2023
作者:
M
Michael Goulet
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Check object's supertrait and associated type bounds in new solver
上级
07c993eb
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
193 addition
and
2 deletion
+193
-2
compiler/rustc_trait_selection/src/solve/assembly.rs
compiler/rustc_trait_selection/src/solve/assembly.rs
+10
-1
compiler/rustc_trait_selection/src/solve/project_goals.rs
compiler/rustc_trait_selection/src/solve/project_goals.rs
+44
-0
compiler/rustc_trait_selection/src/solve/trait_goals.rs
compiler/rustc_trait_selection/src/solve/trait_goals.rs
+39
-0
compiler/rustc_trait_selection/src/solve/trait_goals/structural_traits.rs
...rait_selection/src/solve/trait_goals/structural_traits.rs
+61
-1
tests/ui/traits/new-solver/object-unsafety.rs
tests/ui/traits/new-solver/object-unsafety.rs
+20
-0
tests/ui/traits/new-solver/object-unsafety.stderr
tests/ui/traits/new-solver/object-unsafety.stderr
+19
-0
未找到文件。
compiler/rustc_trait_selection/src/solve/assembly.rs
浏览文件 @
98525aee
...
...
@@ -99,6 +99,15 @@ fn consider_implied_clause(
requirements
:
impl
IntoIterator
<
Item
=
Goal
<
'tcx
,
ty
::
Predicate
<
'tcx
>>>
,
)
->
QueryResult
<
'tcx
>
;
// Consider a clause specifically for a `dyn Trait` self type. This requires
// additionally checking all of the supertraits and object bounds to hold,
// since they're not implied by the well-formedness of the object type.
fn
consider_object_bound_candidate
(
ecx
:
&
mut
EvalCtxt
<
'_
,
'tcx
>
,
goal
:
Goal
<
'tcx
,
Self
>
,
assumption
:
ty
::
Predicate
<
'tcx
>
,
)
->
QueryResult
<
'tcx
>
;
fn
consider_impl_candidate
(
ecx
:
&
mut
EvalCtxt
<
'_
,
'tcx
>
,
goal
:
Goal
<
'tcx
,
Self
>
,
...
...
@@ -455,7 +464,7 @@ fn assemble_object_bound_candidates<G: GoalKind<'tcx>>(
for
assumption
in
elaborate_predicates
(
tcx
,
bounds
.iter
()
.map
(|
bound
|
bound
.with_self_ty
(
tcx
,
self_ty
)))
{
match
G
::
consider_
implied_clause
(
self
,
goal
,
assumption
.predicate
,
[]
)
{
match
G
::
consider_
object_bound_candidate
(
self
,
goal
,
assumption
.predicate
)
{
Ok
(
result
)
=>
{
candidates
.push
(
Candidate
{
source
:
CandidateSource
::
BuiltinImpl
,
result
})
}
...
...
compiler/rustc_trait_selection/src/solve/project_goals.rs
浏览文件 @
98525aee
...
...
@@ -128,6 +128,50 @@ fn consider_implied_clause(
}
}
fn
consider_object_bound_candidate
(
ecx
:
&
mut
EvalCtxt
<
'_
,
'tcx
>
,
goal
:
Goal
<
'tcx
,
Self
>
,
assumption
:
ty
::
Predicate
<
'tcx
>
,
)
->
QueryResult
<
'tcx
>
{
if
let
Some
(
poly_projection_pred
)
=
assumption
.to_opt_poly_projection_pred
()
&&
poly_projection_pred
.projection_def_id
()
==
goal
.predicate
.def_id
()
{
ecx
.probe
(|
ecx
|
{
let
assumption_projection_pred
=
ecx
.instantiate_binder_with_infer
(
poly_projection_pred
);
let
mut
nested_goals
=
ecx
.eq
(
goal
.param_env
,
goal
.predicate.projection_ty
,
assumption_projection_pred
.projection_ty
,
)
?
;
let
tcx
=
ecx
.tcx
();
let
ty
::
Dynamic
(
bounds
,
_
,
_
)
=
*
goal
.predicate
.self_ty
()
.kind
()
else
{
bug!
(
"expected object type in `consider_object_bound_candidate`"
);
};
nested_goals
.extend
(
structural_traits
::
predicates_for_object_candidate
(
tcx
,
goal
.predicate.projection_ty
.trait_ref
(
tcx
),
bounds
,
)
.into_iter
()
.map
(|
pred
|
goal
.with
(
tcx
,
pred
)),
);
let
subst_certainty
=
ecx
.evaluate_all
(
nested_goals
)
?
;
ecx
.eq_term_and_make_canonical_response
(
goal
,
subst_certainty
,
assumption_projection_pred
.term
,
)
})
}
else
{
Err
(
NoSolution
)
}
}
fn
consider_impl_candidate
(
ecx
:
&
mut
EvalCtxt
<
'_
,
'tcx
>
,
goal
:
Goal
<
'tcx
,
ProjectionPredicate
<
'tcx
>>
,
...
...
compiler/rustc_trait_selection/src/solve/trait_goals.rs
浏览文件 @
98525aee
...
...
@@ -86,6 +86,45 @@ fn consider_implied_clause(
}
}
fn
consider_object_bound_candidate
(
ecx
:
&
mut
EvalCtxt
<
'_
,
'tcx
>
,
goal
:
Goal
<
'tcx
,
Self
>
,
assumption
:
ty
::
Predicate
<
'tcx
>
,
)
->
QueryResult
<
'tcx
>
{
if
let
Some
(
poly_trait_pred
)
=
assumption
.to_opt_poly_trait_pred
()
&&
poly_trait_pred
.def_id
()
==
goal
.predicate
.def_id
()
{
// FIXME: Constness and polarity
ecx
.probe
(|
ecx
|
{
let
assumption_trait_pred
=
ecx
.instantiate_binder_with_infer
(
poly_trait_pred
);
let
mut
nested_goals
=
ecx
.eq
(
goal
.param_env
,
goal
.predicate.trait_ref
,
assumption_trait_pred
.trait_ref
,
)
?
;
let
tcx
=
ecx
.tcx
();
let
ty
::
Dynamic
(
bounds
,
_
,
_
)
=
*
goal
.predicate
.self_ty
()
.kind
()
else
{
bug!
(
"expected object type in `consider_object_bound_candidate`"
);
};
nested_goals
.extend
(
structural_traits
::
predicates_for_object_candidate
(
tcx
,
goal
.predicate.trait_ref
,
bounds
,
)
.into_iter
()
.map
(|
pred
|
goal
.with
(
tcx
,
pred
)),
);
ecx
.evaluate_all_and_make_canonical_response
(
nested_goals
)
})
}
else
{
Err
(
NoSolution
)
}
}
fn
consider_auto_trait_candidate
(
ecx
:
&
mut
EvalCtxt
<
'_
,
'tcx
>
,
goal
:
Goal
<
'tcx
,
Self
>
,
...
...
compiler/rustc_trait_selection/src/solve/trait_goals/structural_traits.rs
浏览文件 @
98525aee
use
rustc_data_structures
::
fx
::
FxHashMap
;
use
rustc_hir
::{
Movability
,
Mutability
};
use
rustc_infer
::
traits
::
query
::
NoSolution
;
use
rustc_middle
::
ty
::{
self
,
Ty
,
TyCtxt
};
use
rustc_middle
::
ty
::{
self
,
Ty
,
TyCtxt
,
TypeFoldable
,
TypeFolder
,
TypeSuperFoldable
};
use
crate
::
solve
::
EvalCtxt
;
...
...
@@ -233,3 +234,62 @@ pub(crate) fn extract_tupled_inputs_and_output_from_callable<'tcx>(
}
}
}
pub
(
crate
)
fn
predicates_for_object_candidate
<
'tcx
>
(
tcx
:
TyCtxt
<
'tcx
>
,
trait_ref
:
ty
::
TraitRef
<
'tcx
>
,
object_bound
:
&
'tcx
ty
::
List
<
ty
::
PolyExistentialPredicate
<
'tcx
>>
,
)
->
Vec
<
ty
::
Predicate
<
'tcx
>>
{
let
mut
requirements
=
vec!
[];
requirements
.extend
(
tcx
.super_predicates_of
(
trait_ref
.def_id
)
.instantiate
(
tcx
,
trait_ref
.substs
)
.predicates
,
);
for
item
in
tcx
.associated_items
(
trait_ref
.def_id
)
.in_definition_order
()
{
if
item
.kind
==
ty
::
AssocKind
::
Type
{
requirements
.extend
(
tcx
.item_bounds
(
item
.def_id
)
.subst
(
tcx
,
trait_ref
.substs
));
}
}
let
mut
replace_projection_with
=
FxHashMap
::
default
();
for
bound
in
object_bound
{
let
bound
=
bound
.no_bound_vars
()
.expect
(
"higher-ranked projections not supported, yet"
);
if
let
ty
::
ExistentialPredicate
::
Projection
(
proj
)
=
bound
{
let
proj
=
proj
.with_self_ty
(
tcx
,
trait_ref
.self_ty
());
let
old_ty
=
replace_projection_with
.insert
(
proj
.projection_ty
,
proj
.term
.ty
()
.expect
(
"expected only types in dyn right now"
),
);
assert_eq!
(
old_ty
,
None
,
"{} has two substitutions: {} and {}"
,
proj
.projection_ty
,
proj
.term
,
old_ty
.unwrap
()
);
}
}
requirements
.fold_with
(
&
mut
ReplaceProjectionWith
{
tcx
,
mapping
:
replace_projection_with
})
}
struct
ReplaceProjectionWith
<
'tcx
>
{
tcx
:
TyCtxt
<
'tcx
>
,
mapping
:
FxHashMap
<
ty
::
AliasTy
<
'tcx
>
,
Ty
<
'tcx
>>
,
}
impl
<
'tcx
>
TypeFolder
<
TyCtxt
<
'tcx
>>
for
ReplaceProjectionWith
<
'tcx
>
{
fn
interner
(
&
self
)
->
TyCtxt
<
'tcx
>
{
self
.tcx
}
fn
fold_ty
(
&
mut
self
,
ty
:
Ty
<
'tcx
>
)
->
Ty
<
'tcx
>
{
if
let
ty
::
Alias
(
ty
::
Projection
,
alias_ty
)
=
*
ty
.kind
()
&&
let
Some
(
replacement
)
=
self
.mapping
.get
(
&
alias_ty
)
{
*
replacement
}
else
{
ty
.super_fold_with
(
self
)
}
}
}
tests/ui/traits/new-solver/object-unsafety.rs
0 → 100644
浏览文件 @
98525aee
// compile-flags: -Ztrait-solver=next
trait
Setup
{
type
From
:
Copy
;
}
fn
copy
<
U
:
Setup
+
?
Sized
>
(
from
:
&
U
::
From
)
->
U
::
From
{
*
from
}
pub
fn
copy_any
<
T
>
(
t
:
&
T
)
->
T
{
copy
::
<
dyn
Setup
<
From
=
T
>>
(
t
)
//~^ ERROR the trait bound `dyn Setup<From = T>: Setup` is not satisfied
}
fn
main
()
{
let
x
=
String
::
from
(
"Hello, world"
);
let
y
=
copy_any
(
&
x
);
println!
(
"{y}"
);
}
tests/ui/traits/new-solver/object-unsafety.stderr
0 → 100644
浏览文件 @
98525aee
error[E0277]: the trait bound `dyn Setup<From = T>: Setup` is not satisfied
--> $DIR/object-unsafety.rs:12:12
|
LL | copy::<dyn Setup<From=T>>(t)
| ^^^^^^^^^^^^^^^^^ the trait `Setup` is not implemented for `dyn Setup<From = T>`
|
note: required by a bound in `copy`
--> $DIR/object-unsafety.rs:7:12
|
LL | fn copy<U: Setup + ?Sized>(from: &U::From) -> U::From {
| ^^^^^ required by this bound in `copy`
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
|
LL | pub fn copy_any<T>(t: &T) -> T where dyn Setup<From = T>: Setup {
| ++++++++++++++++++++++++++++++++
error: aborting due to previous error
For more information about this error, try `rustc --explain E0277`.
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录