Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
baf382e6
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,发现更多精彩内容 >>
提交
baf382e6
编写于
6月 28, 2022
作者:
B
bors
浏览文件
操作
浏览文件
下载
差异文件
Auto merge of #98396 - cjgillot:iwfchir, r=petrochenkov
Do not access HIR to check impl wf. r? `
@ghost
`
上级
64eb9ab8
8242aa83
变更
8
隐藏空白更改
内联
并排
Showing
8 changed file
with
49 addition
and
74 deletion
+49
-74
compiler/rustc_typeck/src/impl_wf_check.rs
compiler/rustc_typeck/src/impl_wf_check.rs
+19
-28
compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs
...iler/rustc_typeck/src/impl_wf_check/min_specialization.rs
+14
-27
src/test/ui/associated-item/associated-item-duplicate-names-2.stderr
.../associated-item/associated-item-duplicate-names-2.stderr
+1
-1
src/test/ui/error-codes/E0201.stderr
src/test/ui/error-codes/E0201.stderr
+4
-4
src/test/ui/impl-duplicate-methods.stderr
src/test/ui/impl-duplicate-methods.stderr
+2
-2
src/test/ui/issues/issue-4265.stderr
src/test/ui/issues/issue-4265.stderr
+5
-8
src/test/ui/methods/method-macro-backtrace.stderr
src/test/ui/methods/method-macro-backtrace.stderr
+2
-2
src/test/ui/traits/issue-8153.stderr
src/test/ui/traits/issue-8153.stderr
+2
-2
未找到文件。
compiler/rustc_typeck/src/impl_wf_check.rs
浏览文件 @
baf382e6
...
@@ -13,7 +13,6 @@
...
@@ -13,7 +13,6 @@
use
rustc_data_structures
::
fx
::{
FxHashMap
,
FxHashSet
};
use
rustc_data_structures
::
fx
::{
FxHashMap
,
FxHashSet
};
use
rustc_errors
::
struct_span_err
;
use
rustc_errors
::
struct_span_err
;
use
rustc_hir
as
hir
;
use
rustc_hir
::
def
::
DefKind
;
use
rustc_hir
::
def
::
DefKind
;
use
rustc_hir
::
def_id
::
LocalDefId
;
use
rustc_hir
::
def_id
::
LocalDefId
;
use
rustc_middle
::
ty
::
query
::
Providers
;
use
rustc_middle
::
ty
::
query
::
Providers
;
...
@@ -59,13 +58,10 @@ fn check_mod_impl_wf(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
...
@@ -59,13 +58,10 @@ fn check_mod_impl_wf(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
let
module
=
tcx
.hir_module_items
(
module_def_id
);
let
module
=
tcx
.hir_module_items
(
module_def_id
);
for
id
in
module
.items
()
{
for
id
in
module
.items
()
{
if
matches!
(
tcx
.def_kind
(
id
.def_id
),
DefKind
::
Impl
)
{
if
matches!
(
tcx
.def_kind
(
id
.def_id
),
DefKind
::
Impl
)
{
let
item
=
tcx
.hir
()
.item
(
id
);
enforce_impl_params_are_constrained
(
tcx
,
id
.def_id
);
if
let
hir
::
ItemKind
::
Impl
(
ref
impl_
)
=
item
.kind
{
enforce_impl_items_are_distinct
(
tcx
,
id
.def_id
);
enforce_impl_params_are_constrained
(
tcx
,
item
.def_id
,
impl_
.items
);
if
min_specialization
{
enforce_impl_items_are_distinct
(
tcx
,
impl_
.items
);
check_min_specialization
(
tcx
,
id
.def_id
);
if
min_specialization
{
check_min_specialization
(
tcx
,
item
.def_id
.to_def_id
(),
item
.span
);
}
}
}
}
}
}
}
...
@@ -75,11 +71,7 @@ pub fn provide(providers: &mut Providers) {
...
@@ -75,11 +71,7 @@ pub fn provide(providers: &mut Providers) {
*
providers
=
Providers
{
check_mod_impl_wf
,
..*
providers
};
*
providers
=
Providers
{
check_mod_impl_wf
,
..*
providers
};
}
}
fn
enforce_impl_params_are_constrained
(
fn
enforce_impl_params_are_constrained
(
tcx
:
TyCtxt
<
'_
>
,
impl_def_id
:
LocalDefId
)
{
tcx
:
TyCtxt
<
'_
>
,
impl_def_id
:
LocalDefId
,
impl_item_refs
:
&
[
hir
::
ImplItemRef
],
)
{
// Every lifetime used in an associated type must be constrained.
// Every lifetime used in an associated type must be constrained.
let
impl_self_ty
=
tcx
.type_of
(
impl_def_id
);
let
impl_self_ty
=
tcx
.type_of
(
impl_def_id
);
if
impl_self_ty
.references_error
()
{
if
impl_self_ty
.references_error
()
{
...
@@ -107,9 +99,9 @@ fn enforce_impl_params_are_constrained(
...
@@ -107,9 +99,9 @@ fn enforce_impl_params_are_constrained(
);
);
// Disallow unconstrained lifetimes, but only if they appear in assoc types.
// Disallow unconstrained lifetimes, but only if they appear in assoc types.
let
lifetimes_in_associated_types
:
FxHashSet
<
_
>
=
impl_item_refs
let
lifetimes_in_associated_types
:
FxHashSet
<
_
>
=
tcx
.associated_item_def_ids
(
impl_def_id
)
.iter
()
.iter
()
.map
(|
item_ref
|
item_ref
.id.def_id
)
.flat_map
(|
def_id
|
{
.flat_map
(|
def_id
|
{
let
item
=
tcx
.associated_item
(
def_id
);
let
item
=
tcx
.associated_item
(
def_id
);
match
item
.kind
{
match
item
.kind
{
...
@@ -209,33 +201,32 @@ impl trait, self type, or predicates",
...
@@ -209,33 +201,32 @@ impl trait, self type, or predicates",
}
}
/// Enforce that we do not have two items in an impl with the same name.
/// Enforce that we do not have two items in an impl with the same name.
fn
enforce_impl_items_are_distinct
(
tcx
:
TyCtxt
<
'_
>
,
impl_
item_refs
:
&
[
hir
::
ImplItemRef
]
)
{
fn
enforce_impl_items_are_distinct
(
tcx
:
TyCtxt
<
'_
>
,
impl_
def_id
:
LocalDefId
)
{
let
mut
seen_type_items
=
FxHashMap
::
default
();
let
mut
seen_type_items
=
FxHashMap
::
default
();
let
mut
seen_value_items
=
FxHashMap
::
default
();
let
mut
seen_value_items
=
FxHashMap
::
default
();
for
impl_item_ref
in
impl_item_refs
{
for
&
impl_item_ref
in
tcx
.associated_item_def_ids
(
impl_def_id
)
{
let
impl_item
=
tcx
.
hir
()
.impl_item
(
impl_item_ref
.id
);
let
impl_item
=
tcx
.
associated_item
(
impl_item_ref
);
let
seen_items
=
match
impl_item
.kind
{
let
seen_items
=
match
impl_item
.kind
{
hir
::
ImplItemKind
::
TyAlias
(
_
)
=>
&
mut
seen_type_items
,
ty
::
AssocKind
::
Type
=>
&
mut
seen_type_items
,
_
=>
&
mut
seen_value_items
,
_
=>
&
mut
seen_value_items
,
};
};
match
seen_items
.entry
(
impl_item
.ident
.normalize_to_macros_2_0
())
{
let
span
=
tcx
.def_span
(
impl_item_ref
);
let
ident
=
impl_item
.ident
(
tcx
);
match
seen_items
.entry
(
ident
.normalize_to_macros_2_0
())
{
Occupied
(
entry
)
=>
{
Occupied
(
entry
)
=>
{
let
mut
err
=
struct_span_err!
(
let
mut
err
=
struct_span_err!
(
tcx
.sess
,
tcx
.sess
,
impl_item
.
span
,
span
,
E0201
,
E0201
,
"duplicate definitions with name `{}`:"
,
"duplicate definitions with name `{}`:"
,
impl_item
.ident
ident
);
err
.span_label
(
*
entry
.get
(),
format!
(
"previous definition of `{}` here"
,
impl_item
.ident
),
);
);
err
.span_label
(
impl_item
.span
,
"duplicate definition"
);
err
.span_label
(
*
entry
.get
(),
format!
(
"previous definition of `{}` here"
,
ident
));
err
.span_label
(
span
,
"duplicate definition"
);
err
.emit
();
err
.emit
();
}
}
Vacant
(
entry
)
=>
{
Vacant
(
entry
)
=>
{
entry
.insert
(
impl_item
.
span
);
entry
.insert
(
span
);
}
}
}
}
}
}
...
...
compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs
浏览文件 @
baf382e6
...
@@ -79,19 +79,19 @@
...
@@ -79,19 +79,19 @@
use
rustc_span
::
Span
;
use
rustc_span
::
Span
;
use
rustc_trait_selection
::
traits
::{
self
,
translate_substs
,
wf
};
use
rustc_trait_selection
::
traits
::{
self
,
translate_substs
,
wf
};
pub
(
super
)
fn
check_min_specialization
(
tcx
:
TyCtxt
<
'_
>
,
impl_def_id
:
DefId
,
span
:
Span
)
{
pub
(
super
)
fn
check_min_specialization
(
tcx
:
TyCtxt
<
'_
>
,
impl_def_id
:
LocalDefId
)
{
if
let
Some
(
node
)
=
parent_specialization_node
(
tcx
,
impl_def_id
)
{
if
let
Some
(
node
)
=
parent_specialization_node
(
tcx
,
impl_def_id
)
{
tcx
.infer_ctxt
()
.enter
(|
infcx
|
{
tcx
.infer_ctxt
()
.enter
(|
infcx
|
{
check_always_applicable
(
&
infcx
,
impl_def_id
,
node
,
span
);
check_always_applicable
(
&
infcx
,
impl_def_id
,
node
);
});
});
}
}
}
}
fn
parent_specialization_node
(
tcx
:
TyCtxt
<
'_
>
,
impl1_def_id
:
DefId
)
->
Option
<
Node
>
{
fn
parent_specialization_node
(
tcx
:
TyCtxt
<
'_
>
,
impl1_def_id
:
Local
DefId
)
->
Option
<
Node
>
{
let
trait_ref
=
tcx
.impl_trait_ref
(
impl1_def_id
)
?
;
let
trait_ref
=
tcx
.impl_trait_ref
(
impl1_def_id
)
?
;
let
trait_def
=
tcx
.trait_def
(
trait_ref
.def_id
);
let
trait_def
=
tcx
.trait_def
(
trait_ref
.def_id
);
let
impl2_node
=
trait_def
.ancestors
(
tcx
,
impl1_def_id
)
.ok
()
?
.nth
(
1
)
?
;
let
impl2_node
=
trait_def
.ancestors
(
tcx
,
impl1_def_id
.to_def_id
()
)
.ok
()
?
.nth
(
1
)
?
;
let
always_applicable_trait
=
let
always_applicable_trait
=
matches!
(
trait_def
.specialization_kind
,
TraitSpecializationKind
::
AlwaysApplicable
);
matches!
(
trait_def
.specialization_kind
,
TraitSpecializationKind
::
AlwaysApplicable
);
...
@@ -103,15 +103,8 @@ fn parent_specialization_node(tcx: TyCtxt<'_>, impl1_def_id: DefId) -> Option<No
...
@@ -103,15 +103,8 @@ fn parent_specialization_node(tcx: TyCtxt<'_>, impl1_def_id: DefId) -> Option<No
}
}
/// Check that `impl1` is a sound specialization
/// Check that `impl1` is a sound specialization
fn
check_always_applicable
(
fn
check_always_applicable
(
infcx
:
&
InferCtxt
<
'_
,
'_
>
,
impl1_def_id
:
LocalDefId
,
impl2_node
:
Node
)
{
infcx
:
&
InferCtxt
<
'_
,
'_
>
,
if
let
Some
((
impl1_substs
,
impl2_substs
))
=
get_impl_substs
(
infcx
,
impl1_def_id
,
impl2_node
)
{
impl1_def_id
:
DefId
,
impl2_node
:
Node
,
span
:
Span
,
)
{
if
let
Some
((
impl1_substs
,
impl2_substs
))
=
get_impl_substs
(
infcx
,
impl1_def_id
,
impl2_node
,
span
)
{
let
impl2_def_id
=
impl2_node
.def_id
();
let
impl2_def_id
=
impl2_node
.def_id
();
debug!
(
debug!
(
"check_always_applicable(
\n
impl1_def_id={:?},
\n
impl2_def_id={:?},
\n
impl2_substs={:?}
\n
)"
,
"check_always_applicable(
\n
impl1_def_id={:?},
\n
impl2_def_id={:?},
\n
impl2_substs={:?}
\n
)"
,
...
@@ -126,17 +119,10 @@ fn check_always_applicable(
...
@@ -126,17 +119,10 @@ fn check_always_applicable(
unconstrained_parent_impl_substs
(
tcx
,
impl2_def_id
,
impl2_substs
)
unconstrained_parent_impl_substs
(
tcx
,
impl2_def_id
,
impl2_substs
)
};
};
let
span
=
tcx
.def_span
(
impl1_def_id
);
check_static_lifetimes
(
tcx
,
&
parent_substs
,
span
);
check_static_lifetimes
(
tcx
,
&
parent_substs
,
span
);
check_duplicate_params
(
tcx
,
impl1_substs
,
&
parent_substs
,
span
);
check_duplicate_params
(
tcx
,
impl1_substs
,
&
parent_substs
,
span
);
check_predicates
(
infcx
,
impl1_def_id
,
impl1_substs
,
impl2_node
,
impl2_substs
,
span
);
check_predicates
(
infcx
,
impl1_def_id
.expect_local
(),
impl1_substs
,
impl2_node
,
impl2_substs
,
span
,
);
}
}
}
}
...
@@ -152,20 +138,21 @@ fn check_always_applicable(
...
@@ -152,20 +138,21 @@ fn check_always_applicable(
/// Would return `S1 = [C]` and `S2 = [Vec<C>, C]`.
/// Would return `S1 = [C]` and `S2 = [Vec<C>, C]`.
fn
get_impl_substs
<
'tcx
>
(
fn
get_impl_substs
<
'tcx
>
(
infcx
:
&
InferCtxt
<
'_
,
'tcx
>
,
infcx
:
&
InferCtxt
<
'_
,
'tcx
>
,
impl1_def_id
:
DefId
,
impl1_def_id
:
Local
DefId
,
impl2_node
:
Node
,
impl2_node
:
Node
,
span
:
Span
,
)
->
Option
<
(
SubstsRef
<
'tcx
>
,
SubstsRef
<
'tcx
>
)
>
{
)
->
Option
<
(
SubstsRef
<
'tcx
>
,
SubstsRef
<
'tcx
>
)
>
{
let
tcx
=
infcx
.tcx
;
let
tcx
=
infcx
.tcx
;
let
param_env
=
tcx
.param_env
(
impl1_def_id
);
let
param_env
=
tcx
.param_env
(
impl1_def_id
);
let
impl1_substs
=
InternalSubsts
::
identity_for_item
(
tcx
,
impl1_def_id
);
let
impl1_substs
=
InternalSubsts
::
identity_for_item
(
tcx
,
impl1_def_id
.to_def_id
());
let
impl2_substs
=
translate_substs
(
infcx
,
param_env
,
impl1_def_id
,
impl1_substs
,
impl2_node
);
let
impl2_substs
=
translate_substs
(
infcx
,
param_env
,
impl1_def_id
.to_def_id
(),
impl1_substs
,
impl2_node
);
// Conservatively use an empty `ParamEnv`.
// Conservatively use an empty `ParamEnv`.
let
outlives_env
=
OutlivesEnvironment
::
new
(
ty
::
ParamEnv
::
empty
());
let
outlives_env
=
OutlivesEnvironment
::
new
(
ty
::
ParamEnv
::
empty
());
infcx
.resolve_regions_and_report_errors
(
impl1_def_id
,
&
outlives_env
);
infcx
.resolve_regions_and_report_errors
(
impl1_def_id
.to_def_id
()
,
&
outlives_env
);
let
Ok
(
impl2_substs
)
=
infcx
.fully_resolve
(
impl2_substs
)
else
{
let
Ok
(
impl2_substs
)
=
infcx
.fully_resolve
(
impl2_substs
)
else
{
let
span
=
tcx
.def_span
(
impl1_def_id
);
tcx
.sess
.emit_err
(
SubstsOnOverriddenImpl
{
span
});
tcx
.sess
.emit_err
(
SubstsOnOverriddenImpl
{
span
});
return
None
;
return
None
;
};
};
...
...
src/test/ui/associated-item/associated-item-duplicate-names-2.stderr
浏览文件 @
baf382e6
...
@@ -4,7 +4,7 @@ error[E0201]: duplicate definitions with name `bar`:
...
@@ -4,7 +4,7 @@ error[E0201]: duplicate definitions with name `bar`:
LL | const bar: bool = true;
LL | const bar: bool = true;
| ----------------------- previous definition of `bar` here
| ----------------------- previous definition of `bar` here
LL | fn bar() {}
LL | fn bar() {}
| ^^^^^^^^
^^^
duplicate definition
| ^^^^^^^^ duplicate definition
error: aborting due to previous error
error: aborting due to previous error
...
...
src/test/ui/error-codes/E0201.stderr
浏览文件 @
baf382e6
...
@@ -2,17 +2,17 @@ error[E0201]: duplicate definitions with name `bar`:
...
@@ -2,17 +2,17 @@ error[E0201]: duplicate definitions with name `bar`:
--> $DIR/E0201.rs:5:5
--> $DIR/E0201.rs:5:5
|
|
LL | fn bar(&self) -> bool { self.0 > 5 }
LL | fn bar(&self) -> bool { self.0 > 5 }
| ---------------------
---------------
previous definition of `bar` here
| --------------------- previous definition of `bar` here
LL | fn bar() {}
LL | fn bar() {}
| ^^^^^^^^
^^^
duplicate definition
| ^^^^^^^^ duplicate definition
error[E0201]: duplicate definitions with name `baz`:
error[E0201]: duplicate definitions with name `baz`:
--> $DIR/E0201.rs:17:5
--> $DIR/E0201.rs:17:5
|
|
LL | fn baz(&self) -> bool { true }
LL | fn baz(&self) -> bool { true }
| ---------------------
---------
previous definition of `baz` here
| --------------------- previous definition of `baz` here
LL | fn baz(&self) -> bool { self.0 > 5 }
LL | fn baz(&self) -> bool { self.0 > 5 }
| ^^^^^^^^^^^^^^^^^^^^^
^^^^^^^^^^^^^^^
duplicate definition
| ^^^^^^^^^^^^^^^^^^^^^ duplicate definition
error[E0201]: duplicate definitions with name `Quux`:
error[E0201]: duplicate definitions with name `Quux`:
--> $DIR/E0201.rs:18:5
--> $DIR/E0201.rs:18:5
...
...
src/test/ui/impl-duplicate-methods.stderr
浏览文件 @
baf382e6
...
@@ -2,9 +2,9 @@ error[E0201]: duplicate definitions with name `orange`:
...
@@ -2,9 +2,9 @@ error[E0201]: duplicate definitions with name `orange`:
--> $DIR/impl-duplicate-methods.rs:5:5
--> $DIR/impl-duplicate-methods.rs:5:5
|
|
LL | fn orange(&self) {}
LL | fn orange(&self) {}
| ----------------
---
previous definition of `orange` here
| ---------------- previous definition of `orange` here
LL | fn orange(&self) {}
LL | fn orange(&self) {}
| ^^^^^^^^^^^^^^^^
^^^
duplicate definition
| ^^^^^^^^^^^^^^^^ duplicate definition
error: aborting due to previous error
error: aborting due to previous error
...
...
src/test/ui/issues/issue-4265.stderr
浏览文件 @
baf382e6
error[E0201]: duplicate definitions with name `bar`:
error[E0201]: duplicate definitions with name `bar`:
--> $DIR/issue-4265.rs:10:5
--> $DIR/issue-4265.rs:10:5
|
|
LL | / fn bar() {
LL | fn bar() {
LL | | Foo { baz: 0 }.bar();
| -------- previous definition of `bar` here
LL | | }
...
| |_____- previous definition of `bar` here
LL | fn bar() {
LL |
| ^^^^^^^^ duplicate definition
LL | / fn bar() {
LL | | }
| |_____^ duplicate definition
error: aborting due to previous error
error: aborting due to previous error
...
...
src/test/ui/methods/method-macro-backtrace.stderr
浏览文件 @
baf382e6
...
@@ -2,9 +2,9 @@ error[E0201]: duplicate definitions with name `bar`:
...
@@ -2,9 +2,9 @@ error[E0201]: duplicate definitions with name `bar`:
--> $DIR/method-macro-backtrace.rs:22:5
--> $DIR/method-macro-backtrace.rs:22:5
|
|
LL | fn bar(&self) { }
LL | fn bar(&self) { }
| -------------
----
previous definition of `bar` here
| ------------- previous definition of `bar` here
LL | fn bar(&self) { }
LL | fn bar(&self) { }
| ^^^^^^^^^^^^^
^^^^
duplicate definition
| ^^^^^^^^^^^^^ duplicate definition
error: aborting due to previous error
error: aborting due to previous error
...
...
src/test/ui/traits/issue-8153.stderr
浏览文件 @
baf382e6
...
@@ -2,9 +2,9 @@ error[E0201]: duplicate definitions with name `bar`:
...
@@ -2,9 +2,9 @@ error[E0201]: duplicate definitions with name `bar`:
--> $DIR/issue-8153.rs:11:5
--> $DIR/issue-8153.rs:11:5
|
|
LL | fn bar(&self) -> isize {1}
LL | fn bar(&self) -> isize {1}
| ----------------------
----
previous definition of `bar` here
| ---------------------- previous definition of `bar` here
LL | fn bar(&self) -> isize {2}
LL | fn bar(&self) -> isize {2}
| ^^^^^^^^^^^^^^^^^^^^^^
^^^^
duplicate definition
| ^^^^^^^^^^^^^^^^^^^^^^ duplicate definition
error: aborting due to previous error
error: aborting due to previous error
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录