Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
626abc79
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,发现更多精彩内容 >>
提交
626abc79
编写于
3月 23, 2020
作者:
E
Eduard-Mihai Burtescu
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
ty: remove `{Existential,}Trait{Ref,Predicate}::input_types`.
上级
b7fdc7b6
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
103 addition
and
107 deletion
+103
-107
src/librustc_middle/ty/mod.rs
src/librustc_middle/ty/mod.rs
+0
-4
src/librustc_middle/ty/sty.rs
src/librustc_middle/ty/sty.rs
+0
-16
src/librustc_trait_selection/traits/coherence.rs
src/librustc_trait_selection/traits/coherence.rs
+7
-3
src/librustc_trait_selection/traits/object_safety.rs
src/librustc_trait_selection/traits/object_safety.rs
+5
-9
src/librustc_trait_selection/traits/select.rs
src/librustc_trait_selection/traits/select.rs
+27
-11
src/librustc_typeck/check/coercion.rs
src/librustc_typeck/check/coercion.rs
+12
-12
src/librustdoc/clean/mod.rs
src/librustdoc/clean/mod.rs
+52
-52
未找到文件。
src/librustc_middle/ty/mod.rs
浏览文件 @
626abc79
...
...
@@ -1365,10 +1365,6 @@ pub fn def_id(&self) -> DefId {
self
.trait_ref.def_id
}
pub
fn
input_types
<
'a
>
(
&
'a
self
)
->
impl
DoubleEndedIterator
<
Item
=
Ty
<
'tcx
>>
+
'a
{
self
.trait_ref
.input_types
()
}
pub
fn
self_ty
(
&
self
)
->
Ty
<
'tcx
>
{
self
.trait_ref
.self_ty
()
}
...
...
src/librustc_middle/ty/sty.rs
浏览文件 @
626abc79
...
...
@@ -754,14 +754,6 @@ pub fn self_ty(&self) -> Ty<'tcx> {
self
.substs
.type_at
(
0
)
}
pub
fn
input_types
<
'a
>
(
&
'a
self
)
->
impl
DoubleEndedIterator
<
Item
=
Ty
<
'tcx
>>
+
'a
{
// Select only the "input types" from a trait-reference. For
// now this is all the types that appear in the
// trait-reference, but it should eventually exclude
// associated types.
self
.substs
.types
()
}
pub
fn
from_method
(
tcx
:
TyCtxt
<
'tcx
>
,
trait_id
:
DefId
,
...
...
@@ -805,14 +797,6 @@ pub struct ExistentialTraitRef<'tcx> {
}
impl
<
'tcx
>
ExistentialTraitRef
<
'tcx
>
{
pub
fn
input_types
<
'b
>
(
&
'b
self
)
->
impl
DoubleEndedIterator
<
Item
=
Ty
<
'tcx
>>
+
'b
{
// Select only the "input types" from a trait-reference. For
// now this is all the types that appear in the
// trait-reference, but it should eventually exclude
// associated types.
self
.substs
.types
()
}
pub
fn
erase_self_ty
(
tcx
:
TyCtxt
<
'tcx
>
,
trait_ref
:
ty
::
TraitRef
<
'tcx
>
,
...
...
src/librustc_trait_selection/traits/coherence.rs
浏览文件 @
626abc79
...
...
@@ -393,8 +393,11 @@ fn uncover_fundamental_ty<'tcx>(
}
let
mut
non_local_spans
=
vec!
[];
for
(
i
,
input_ty
)
in
trait_ref
.input_types
()
.flat_map
(|
ty
|
uncover_fundamental_ty
(
tcx
,
ty
,
in_crate
))
.enumerate
()
for
(
i
,
input_ty
)
in
trait_ref
.substs
.types
()
.flat_map
(|
ty
|
uncover_fundamental_ty
(
tcx
,
ty
,
in_crate
))
.enumerate
()
{
debug!
(
"orphan_check_trait_ref: check ty `{:?}`"
,
input_ty
);
let
non_local_tys
=
ty_is_non_local
(
tcx
,
input_ty
,
in_crate
);
...
...
@@ -404,7 +407,8 @@ fn uncover_fundamental_ty<'tcx>(
}
else
if
let
ty
::
Param
(
_
)
=
input_ty
.kind
{
debug!
(
"orphan_check_trait_ref: uncovered ty: `{:?}`"
,
input_ty
);
let
local_type
=
trait_ref
.input_types
()
.substs
.types
()
.flat_map
(|
ty
|
uncover_fundamental_ty
(
tcx
,
ty
,
in_crate
))
.find
(|
ty
|
ty_is_non_local_constructor
(
ty
,
in_crate
)
.is_none
());
...
...
src/librustc_trait_selection/traits/object_safety.rs
浏览文件 @
626abc79
...
...
@@ -16,7 +16,7 @@
use
rustc_errors
::{
Applicability
,
FatalError
};
use
rustc_hir
as
hir
;
use
rustc_hir
::
def_id
::
DefId
;
use
rustc_middle
::
ty
::
subst
::{
GenericArgKind
,
InternalSubsts
,
Subst
};
use
rustc_middle
::
ty
::
subst
::{
GenericArg
,
GenericArg
Kind
,
InternalSubsts
,
Subst
};
use
rustc_middle
::
ty
::{
self
,
Predicate
,
ToPredicate
,
Ty
,
TyCtxt
,
TypeFoldable
,
WithConstness
};
use
rustc_session
::
lint
::
builtin
::
WHERE_CLAUSES_OBJECT_SAFETY
;
use
rustc_span
::
symbol
::
Symbol
;
...
...
@@ -234,7 +234,7 @@ fn predicates_reference_self(
tcx
.predicates_of
(
trait_def_id
)
};
let
self_ty
=
tcx
.types.self_param
;
let
has_self_ty
=
|
t
:
Ty
<
'_
>
|
t
.walk
()
.any
(|
arg
|
arg
==
self_ty
.into
());
let
has_self_ty
=
|
arg
:
&
GenericArg
<
'_
>
|
arg
.walk
()
.any
(|
arg
|
arg
==
self_ty
.into
());
predicates
.predicates
.iter
()
...
...
@@ -243,7 +243,7 @@ fn predicates_reference_self(
match
predicate
{
ty
::
Predicate
::
Trait
(
ref
data
,
_
)
=>
{
// In the case of a trait predicate, we can skip the "self" type.
if
data
.skip_binder
()
.
input_types
()
.skip
(
1
)
.any
(
has_self_ty
)
{
if
data
.skip_binder
()
.
trait_ref.substs
[
1
..
]
.iter
(
)
.any
(
has_self_ty
)
{
Some
(
sp
)
}
else
{
None
...
...
@@ -262,12 +262,8 @@ fn predicates_reference_self(
//
// This is ALT2 in issue #56288, see that for discussion of the
// possible alternatives.
if
data
.skip_binder
()
.projection_ty
.trait_ref
(
tcx
)
.input_types
()
.skip
(
1
)
if
data
.skip_binder
()
.projection_ty
.trait_ref
(
tcx
)
.substs
[
1
..
]
.iter
()
.any
(
has_self_ty
)
{
Some
(
sp
)
...
...
src/librustc_trait_selection/traits/select.rs
浏览文件 @
626abc79
...
...
@@ -652,7 +652,7 @@ fn evaluate_stack<'o>(
&
mut
self
,
stack
:
&
TraitObligationStack
<
'o
,
'tcx
>
,
)
->
Result
<
EvaluationResult
,
OverflowError
>
{
// In intercrate mode, whenever any of the
type
s are unbound,
// In intercrate mode, whenever any of the
generic
s are unbound,
// there can always be an impl. Even if there are no impls in
// this crate, perhaps the type would be unified with
// something from another crate that does provide an impl.
...
...
@@ -677,7 +677,7 @@ fn evaluate_stack<'o>(
// terms of `Fn` etc, but we could probably make this more
// precise still.
let
unbound_input_types
=
stack
.fresh_trait_ref
.skip_binder
()
.
input_
types
()
.any
(|
ty
|
ty
.is_fresh
());
stack
.fresh_trait_ref
.skip_binder
()
.
substs
.
types
()
.any
(|
ty
|
ty
.is_fresh
());
// This check was an imperfect workaround for a bug in the old
// intercrate mode; it should be removed when that goes away.
if
unbound_input_types
&&
self
.intercrate
{
...
...
@@ -3262,15 +3262,31 @@ fn fast_reject_trait_refs(
// substitution if we find that any of the input types, when
// simplified, do not match.
obligation
.predicate
.skip_binder
()
.input_types
()
.zip
(
impl_trait_ref
.input_types
())
.any
(
|(
obligation_ty
,
impl_ty
)|
{
let
simplified_obligation_ty
=
fast_reject
::
simplify_type
(
self
.tcx
(),
obligation_ty
,
true
);
let
simplified_impl_ty
=
fast_reject
::
simplify_type
(
self
.tcx
(),
impl_ty
,
false
);
simplified_obligation_ty
.is_some
()
&&
simplified_impl_ty
.is_some
()
&&
simplified_obligation_ty
!=
simplified_impl_ty
obligation
.predicate
.skip_binder
()
.trait_ref.substs
.iter
()
.zip
(
impl_trait_ref
.substs
)
.any
(
|(
obligation_arg
,
impl_arg
)|
{
match
(
obligation_arg
.unpack
(),
impl_arg
.unpack
())
{
(
GenericArgKind
::
Type
(
obligation_ty
),
GenericArgKind
::
Type
(
impl_ty
))
=>
{
let
simplified_obligation_ty
=
fast_reject
::
simplify_type
(
self
.tcx
(),
obligation_ty
,
true
);
let
simplified_impl_ty
=
fast_reject
::
simplify_type
(
self
.tcx
(),
impl_ty
,
false
);
simplified_obligation_ty
.is_some
()
&&
simplified_impl_ty
.is_some
()
&&
simplified_obligation_ty
!=
simplified_impl_ty
}
(
GenericArgKind
::
Lifetime
(
_
),
GenericArgKind
::
Lifetime
(
_
))
=>
{
// Lifetimes can never cause a rejection.
false
}
(
GenericArgKind
::
Const
(
_
),
GenericArgKind
::
Const
(
_
))
=>
{
// Conservatively ignore consts (i.e. assume they might
// unify later) until we have `fast_reject` support for
// them (if we'll ever need it, even).
false
}
_
=>
unreachable!
(),
}
},
)
}
...
...
src/librustc_typeck/check/coercion.rs
浏览文件 @
626abc79
...
...
@@ -563,30 +563,30 @@ fn coerce_unsized(&self, source: Ty<'tcx>, target: Ty<'tcx>) -> CoerceResult<'tc
while
!
queue
.is_empty
()
{
let
obligation
=
queue
.remove
(
0
);
debug!
(
"coerce_unsized resolve step: {:?}"
,
obligation
);
let
trait_
ref
=
match
obligation
.predicate
{
ty
::
Predicate
::
Trait
(
ref
tr
,
_
)
if
traits
.contains
(
&
tr
.def_id
())
=>
{
if
unsize_did
==
tr
.def_id
()
{
let
sty
=
&
tr
.skip_binder
()
.input_types
()
.nth
(
1
)
.unwrap
()
.kind
;
if
let
ty
::
Tuple
(
..
)
=
sty
{
let
trait_
pred
=
match
obligation
.predicate
{
ty
::
Predicate
::
Trait
(
trait_pred
,
_
)
if
traits
.contains
(
&
trait_pred
.def_id
())
=>
{
if
unsize_did
==
tr
ait_pred
.def_id
()
{
let
unsize_ty
=
trait_pred
.skip_binder
()
.trait_ref.substs
[
1
]
.expect_ty
()
;
if
let
ty
::
Tuple
(
..
)
=
unsize_ty
.kind
{
debug!
(
"coerce_unsized: found unsized tuple coercion"
);
has_unsized_tuple_coercion
=
true
;
}
}
*
tr
trait_pred
}
_
=>
{
coercion
.obligations
.push
(
obligation
);
continue
;
}
};
match
selcx
.select
(
&
obligation
.with
(
trait_
ref
))
{
match
selcx
.select
(
&
obligation
.with
(
trait_
pred
))
{
// Uncertain or unimplemented.
Ok
(
None
)
=>
{
if
trait_
ref
.def_id
()
==
unsize_did
{
let
trait_
ref
=
self
.resolve_vars_if_possible
(
&
trait_ref
);
let
self_ty
=
trait_
ref
.skip_binder
()
.self_ty
();
let
unsize_ty
=
trait_
ref
.skip_binder
()
.input_types
()
.nth
(
1
)
.unwrap
();
debug!
(
"coerce_unsized: ambiguous unsize case for {:?}"
,
trait_
ref
);
if
trait_
pred
.def_id
()
==
unsize_did
{
let
trait_
pred
=
self
.resolve_vars_if_possible
(
&
trait_pred
);
let
self_ty
=
trait_
pred
.skip_binder
()
.self_ty
();
let
unsize_ty
=
trait_
pred
.skip_binder
()
.trait_ref.substs
[
1
]
.expect_ty
();
debug!
(
"coerce_unsized: ambiguous unsize case for {:?}"
,
trait_
pred
);
match
(
&
self_ty
.kind
,
&
unsize_ty
.kind
)
{
(
ty
::
Infer
(
ty
::
TyVar
(
v
)),
ty
::
Dynamic
(
..
))
if
self
.type_var_is_sized
(
*
v
)
=>
...
...
src/librustdoc/clean/mod.rs
浏览文件 @
626abc79
...
...
@@ -84,15 +84,6 @@ fn clean(&self, cx: &DocContext<'_>) -> Option<U> {
}
}
impl
<
T
,
U
>
Clean
<
U
>
for
ty
::
Binder
<
T
>
where
T
:
Clean
<
U
>
,
{
fn
clean
(
&
self
,
cx
:
&
DocContext
<
'_
>
)
->
U
{
self
.skip_binder
()
.clean
(
cx
)
}
}
impl
Clean
<
ExternalCrate
>
for
CrateNum
{
fn
clean
(
&
self
,
cx
:
&
DocContext
<
'_
>
)
->
ExternalCrate
{
let
root
=
DefId
{
krate
:
*
self
,
index
:
CRATE_DEF_INDEX
};
...
...
@@ -305,59 +296,66 @@ fn clean(&self, cx: &DocContext<'_>) -> GenericBound {
}
}
impl
<
'a
,
'tcx
>
Clean
<
GenericBound
>
for
(
&
'a
ty
::
TraitRef
<
'tcx
>
,
Vec
<
TypeBinding
>
)
{
fn
clean
(
&
self
,
cx
:
&
DocContext
<
'_
>
)
->
GenericBound
{
let
(
trait_ref
,
ref
bounds
)
=
*
self
;
impl
Clean
<
Type
>
for
(
ty
::
TraitRef
<
'_
>
,
&
[
TypeBinding
]
)
{
fn
clean
(
&
self
,
cx
:
&
DocContext
<
'_
>
)
->
Type
{
let
(
trait_ref
,
bounds
)
=
*
self
;
inline
::
record_extern_fqn
(
cx
,
trait_ref
.def_id
,
TypeKind
::
Trait
);
let
path
=
external_path
(
cx
,
cx
.tcx
.item_name
(
trait_ref
.def_id
),
Some
(
trait_ref
.def_id
),
true
,
bounds
.
clone
(),
bounds
.
to_vec
(),
trait_ref
.substs
,
);
debug!
(
"ty::TraitRef
\n
subst: {:?}
\n
"
,
trait_ref
.substs
);
ResolvedPath
{
path
,
param_names
:
None
,
did
:
trait_ref
.def_id
,
is_generic
:
false
}
}
}
impl
<
'tcx
>
Clean
<
GenericBound
>
for
ty
::
TraitRef
<
'tcx
>
{
fn
clean
(
&
self
,
cx
:
&
DocContext
<
'_
>
)
->
GenericBound
{
GenericBound
::
TraitBound
(
PolyTrait
{
trait_
:
(
*
self
,
&
[][
..
])
.clean
(
cx
),
generic_params
:
vec!
[]
},
hir
::
TraitBoundModifier
::
None
,
)
}
}
impl
Clean
<
GenericBound
>
for
(
ty
::
PolyTraitRef
<
'_
>
,
&
[
TypeBinding
])
{
fn
clean
(
&
self
,
cx
:
&
DocContext
<
'_
>
)
->
GenericBound
{
let
(
poly_trait_ref
,
bounds
)
=
*
self
;
let
poly_trait_ref
=
poly_trait_ref
.lift_to_tcx
(
cx
.tcx
)
.unwrap
();
// collect any late bound regions
let
mut
late_bounds
=
vec!
[];
for
ty_s
in
trait_ref
.input_types
()
.skip
(
1
)
{
if
let
ty
::
Tuple
(
ts
)
=
ty_s
.kind
{
for
&
ty_s
in
ts
{
if
let
ty
::
Ref
(
ref
reg
,
_
,
_
)
=
ty_s
.expect_ty
()
.kind
{
if
let
&
ty
::
RegionKind
::
ReLateBound
(
..
)
=
*
reg
{
debug!
(
" hit an ReLateBound {:?}"
,
reg
);
if
let
Some
(
Lifetime
(
name
))
=
reg
.clean
(
cx
)
{
late_bounds
.push
(
GenericParamDef
{
name
,
kind
:
GenericParamDefKind
::
Lifetime
,
});
}
}
}
}
}
}
let
late_bound_regions
:
Vec
<
_
>
=
cx
.tcx
.collect_referenced_late_bound_regions
(
&
poly_trait_ref
)
.into_iter
()
.filter_map
(|
br
|
match
br
{
ty
::
BrNamed
(
_
,
name
)
=>
Some
(
GenericParamDef
{
name
:
name
.to_string
(),
kind
:
GenericParamDefKind
::
Lifetime
,
}),
_
=>
None
,
})
.collect
();
GenericBound
::
TraitBound
(
PolyTrait
{
trait_
:
ResolvedPath
{
path
,
param_names
:
None
,
did
:
trait_ref
.def_id
,
is_generic
:
false
,
},
generic_params
:
late_bounds
,
trait_
:
(
*
poly_trait_ref
.skip_binder
(),
bounds
)
.clean
(
cx
),
generic_params
:
late_bound_regions
,
},
hir
::
TraitBoundModifier
::
None
,
)
}
}
impl
<
'tcx
>
Clean
<
GenericBound
>
for
ty
::
TraitRef
<
'tcx
>
{
impl
<
'tcx
>
Clean
<
GenericBound
>
for
ty
::
Poly
TraitRef
<
'tcx
>
{
fn
clean
(
&
self
,
cx
:
&
DocContext
<
'_
>
)
->
GenericBound
{
(
self
,
vec!
[
])
.clean
(
cx
)
(
*
self
,
&
[][
..
])
.clean
(
cx
)
}
}
...
...
@@ -495,16 +493,17 @@ fn clean(&self, cx: &DocContext<'_>) -> Option<WherePredicate> {
}
}
impl
<
'a
>
Clean
<
WherePredicate
>
for
ty
::
TraitPredicate
<
'a
>
{
impl
<
'a
>
Clean
<
WherePredicate
>
for
ty
::
Poly
TraitPredicate
<
'a
>
{
fn
clean
(
&
self
,
cx
:
&
DocContext
<
'_
>
)
->
WherePredicate
{
let
poly_trait_ref
=
self
.map_bound
(|
pred
|
pred
.trait_ref
);
WherePredicate
::
BoundPredicate
{
ty
:
self
.
trait_ref
.self_ty
()
.clean
(
cx
),
bounds
:
vec!
[
self
.
trait_ref
.clean
(
cx
)],
ty
:
poly_
trait_ref
.self_ty
()
.clean
(
cx
),
bounds
:
vec!
[
poly_
trait_ref
.clean
(
cx
)],
}
}
}
impl
<
'tcx
>
Clean
<
WherePredicate
>
for
ty
::
SubtypePredicate
<
'tcx
>
{
impl
<
'tcx
>
Clean
<
WherePredicate
>
for
ty
::
Poly
SubtypePredicate
<
'tcx
>
{
fn
clean
(
&
self
,
_
cx
:
&
DocContext
<
'_
>
)
->
WherePredicate
{
panic!
(
"subtype predicates are an internal rustc artifact
\
...
...
@@ -514,10 +513,10 @@ fn clean(&self, _cx: &DocContext<'_>) -> WherePredicate {
}
impl
<
'tcx
>
Clean
<
Option
<
WherePredicate
>>
for
ty
::
OutlivesPredicate
<
ty
::
Region
<
'tcx
>
,
ty
::
Region
<
'tcx
>>
for
ty
::
Poly
OutlivesPredicate
<
ty
::
Region
<
'tcx
>
,
ty
::
Region
<
'tcx
>>
{
fn
clean
(
&
self
,
cx
:
&
DocContext
<
'_
>
)
->
Option
<
WherePredicate
>
{
let
ty
::
OutlivesPredicate
(
ref
a
,
ref
b
)
=
*
self
;
let
ty
::
OutlivesPredicate
(
a
,
b
)
=
self
.skip_binder
()
;
if
let
(
ty
::
ReEmpty
(
_
),
ty
::
ReEmpty
(
_
))
=
(
a
,
b
)
{
return
None
;
...
...
@@ -530,9 +529,9 @@ fn clean(&self, cx: &DocContext<'_>) -> Option<WherePredicate> {
}
}
impl
<
'tcx
>
Clean
<
Option
<
WherePredicate
>>
for
ty
::
OutlivesPredicate
<
Ty
<
'tcx
>
,
ty
::
Region
<
'tcx
>>
{
impl
<
'tcx
>
Clean
<
Option
<
WherePredicate
>>
for
ty
::
Poly
OutlivesPredicate
<
Ty
<
'tcx
>
,
ty
::
Region
<
'tcx
>>
{
fn
clean
(
&
self
,
cx
:
&
DocContext
<
'_
>
)
->
Option
<
WherePredicate
>
{
let
ty
::
OutlivesPredicate
(
ref
ty
,
ref
lt
)
=
*
self
;
let
ty
::
OutlivesPredicate
(
ty
,
lt
)
=
self
.skip_binder
()
;
if
let
ty
::
ReEmpty
(
_
)
=
lt
{
return
None
;
...
...
@@ -545,9 +544,10 @@ fn clean(&self, cx: &DocContext<'_>) -> Option<WherePredicate> {
}
}
impl
<
'tcx
>
Clean
<
WherePredicate
>
for
ty
::
ProjectionPredicate
<
'tcx
>
{
impl
<
'tcx
>
Clean
<
WherePredicate
>
for
ty
::
P
olyP
rojectionPredicate
<
'tcx
>
{
fn
clean
(
&
self
,
cx
:
&
DocContext
<
'_
>
)
->
WherePredicate
{
WherePredicate
::
EqPredicate
{
lhs
:
self
.projection_ty
.clean
(
cx
),
rhs
:
self
.ty
.clean
(
cx
)
}
let
ty
::
ProjectionPredicate
{
projection_ty
,
ty
}
=
*
self
.skip_binder
();
WherePredicate
::
EqPredicate
{
lhs
:
projection_ty
.clean
(
cx
),
rhs
:
ty
.clean
(
cx
)
}
}
}
...
...
@@ -1674,7 +1674,7 @@ fn clean(&self, cx: &DocContext<'_>) -> Type {
}
}
let
bounds
=
bounds
let
bounds
:
Vec
<
_
>
=
bounds
.predicates
.iter
()
.filter_map
(|
pred
|
{
...
...
@@ -1703,7 +1703,7 @@ fn clean(&self, cx: &DocContext<'_>) -> Type {
})
.collect
();
Some
((
trait_ref
.skip_binder
(),
bounds
)
.clean
(
cx
))
Some
((
trait_ref
,
&
bounds
[
..
]
)
.clean
(
cx
))
})
.collect
::
<
Vec
<
_
>>
();
bounds
.extend
(
regions
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录