Merge pull request #21460 from Veykril/push-vyqmuvkouywu
feat: Implement support for `feature(new_range)`
This commit is contained in:
commit
cc24765f3c
8 changed files with 246 additions and 128 deletions
|
|
@ -499,6 +499,11 @@ language_item_table! { LangItems =>
|
|||
RangeToInclusive, sym::RangeToInclusive, StructId;
|
||||
RangeTo, sym::RangeTo, StructId;
|
||||
|
||||
RangeFromCopy, sym::RangeFromCopy, StructId;
|
||||
RangeInclusiveCopy, sym::RangeInclusiveCopy, StructId;
|
||||
RangeCopy, sym::RangeCopy, StructId;
|
||||
RangeToInclusiveCopy, sym::RangeToInclusiveCopy, StructId;
|
||||
|
||||
String, sym::String, StructId;
|
||||
CStr, sym::CStr, StructId;
|
||||
Ordering, sym::Ordering, EnumId;
|
||||
|
|
|
|||
|
|
@ -423,6 +423,10 @@ macro_rules! __known_path {
|
|||
(core::ops::RangeTo) => {};
|
||||
(core::ops::RangeToInclusive) => {};
|
||||
(core::ops::RangeInclusive) => {};
|
||||
(core::range::Range) => {};
|
||||
(core::range::RangeFrom) => {};
|
||||
(core::range::RangeInclusive) => {};
|
||||
(core::range::RangeToInclusive) => {};
|
||||
(core::future::Future) => {};
|
||||
(core::future::IntoFuture) => {};
|
||||
(core::fmt::Debug) => {};
|
||||
|
|
|
|||
|
|
@ -1815,18 +1815,34 @@ impl<'body, 'db> InferenceContext<'body, 'db> {
|
|||
Some(struct_.into())
|
||||
}
|
||||
|
||||
fn has_new_range_feature(&self) -> bool {
|
||||
self.resolver.top_level_def_map().is_unstable_feature_enabled(&sym::new_range)
|
||||
}
|
||||
|
||||
fn resolve_range(&self) -> Option<AdtId> {
|
||||
let struct_ = self.lang_items.Range?;
|
||||
let struct_ = if self.has_new_range_feature() {
|
||||
self.lang_items.RangeCopy?
|
||||
} else {
|
||||
self.lang_items.Range?
|
||||
};
|
||||
Some(struct_.into())
|
||||
}
|
||||
|
||||
fn resolve_range_inclusive(&self) -> Option<AdtId> {
|
||||
let struct_ = self.lang_items.RangeInclusiveStruct?;
|
||||
let struct_ = if self.has_new_range_feature() {
|
||||
self.lang_items.RangeInclusiveCopy?
|
||||
} else {
|
||||
self.lang_items.RangeInclusiveStruct?
|
||||
};
|
||||
Some(struct_.into())
|
||||
}
|
||||
|
||||
fn resolve_range_from(&self) -> Option<AdtId> {
|
||||
let struct_ = self.lang_items.RangeFrom?;
|
||||
let struct_ = if self.has_new_range_feature() {
|
||||
self.lang_items.RangeFromCopy?
|
||||
} else {
|
||||
self.lang_items.RangeFrom?
|
||||
};
|
||||
Some(struct_.into())
|
||||
}
|
||||
|
||||
|
|
@ -1836,7 +1852,11 @@ impl<'body, 'db> InferenceContext<'body, 'db> {
|
|||
}
|
||||
|
||||
fn resolve_range_to_inclusive(&self) -> Option<AdtId> {
|
||||
let struct_ = self.lang_items.RangeToInclusive?;
|
||||
let struct_ = if self.has_new_range_feature() {
|
||||
self.lang_items.RangeToInclusiveCopy?
|
||||
} else {
|
||||
self.lang_items.RangeToInclusive?
|
||||
};
|
||||
Some(struct_.into())
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,11 +13,11 @@ fn infer_pattern() {
|
|||
let a = z;
|
||||
let (c, d) = (1, "hello");
|
||||
|
||||
for (e, f) in some_iter {
|
||||
for (e, f) in [(0, 1)] {
|
||||
let g = e;
|
||||
}
|
||||
|
||||
if let [val] = opt {
|
||||
if let [val] = [y] {
|
||||
let h = val;
|
||||
}
|
||||
|
||||
|
|
@ -33,7 +33,7 @@ fn infer_pattern() {
|
|||
"#,
|
||||
expect![[r#"
|
||||
8..9 'x': &'? i32
|
||||
17..400 '{ ...o_x; }': ()
|
||||
17..399 '{ ...o_x; }': ()
|
||||
27..28 'y': &'? i32
|
||||
31..32 'x': &'? i32
|
||||
42..44 '&z': &'? i32
|
||||
|
|
@ -47,58 +47,62 @@ fn infer_pattern() {
|
|||
82..94 '(1, "hello")': (i32, &'? str)
|
||||
83..84 '1': i32
|
||||
86..93 '"hello"': &'static str
|
||||
101..151 'for (e... }': fn into_iter<{unknown}>({unknown}) -> <{unknown} as IntoIterator>::IntoIter
|
||||
101..151 'for (e... }': <{unknown} as IntoIterator>::IntoIter
|
||||
101..151 'for (e... }': !
|
||||
101..151 'for (e... }': {unknown}
|
||||
101..151 'for (e... }': &'? mut {unknown}
|
||||
101..151 'for (e... }': fn next<{unknown}>(&'? mut {unknown}) -> Option<<{unknown} as Iterator>::Item>
|
||||
101..151 'for (e... }': Option<<{unknown} as Iterator>::Item>
|
||||
101..151 'for (e... }': ()
|
||||
101..151 'for (e... }': ()
|
||||
101..151 'for (e... }': ()
|
||||
101..151 'for (e... }': ()
|
||||
105..111 '(e, f)': ({unknown}, {unknown})
|
||||
106..107 'e': {unknown}
|
||||
109..110 'f': {unknown}
|
||||
115..124 'some_iter': {unknown}
|
||||
125..151 '{ ... }': ()
|
||||
139..140 'g': {unknown}
|
||||
143..144 'e': {unknown}
|
||||
157..204 'if let... }': ()
|
||||
160..175 'let [val] = opt': bool
|
||||
164..169 '[val]': [{unknown}]
|
||||
165..168 'val': {unknown}
|
||||
172..175 'opt': [{unknown}]
|
||||
176..204 '{ ... }': ()
|
||||
190..191 'h': {unknown}
|
||||
194..197 'val': {unknown}
|
||||
210..236 'if let...rue {}': ()
|
||||
213..233 'let x ... &true': bool
|
||||
217..225 'x @ true': &'? bool
|
||||
221..225 'true': bool
|
||||
221..225 'true': bool
|
||||
228..233 '&true': &'? bool
|
||||
229..233 'true': bool
|
||||
234..236 '{}': ()
|
||||
246..252 'lambda': impl Fn(u64, u64, i32) -> i32
|
||||
255..287 '|a: u6...b; c }': impl Fn(u64, u64, i32) -> i32
|
||||
256..257 'a': u64
|
||||
264..265 'b': u64
|
||||
267..268 'c': i32
|
||||
275..287 '{ a + b; c }': i32
|
||||
277..278 'a': u64
|
||||
277..282 'a + b': u64
|
||||
281..282 'b': u64
|
||||
284..285 'c': i32
|
||||
298..310 'ref ref_to_x': &'? &'? i32
|
||||
313..314 'x': &'? i32
|
||||
324..333 'mut mut_x': &'? i32
|
||||
336..337 'x': &'? i32
|
||||
347..367 'ref mu...f_to_x': &'? mut &'? i32
|
||||
370..371 'x': &'? i32
|
||||
381..382 'k': &'? mut &'? i32
|
||||
385..397 'mut_ref_to_x': &'? mut &'? i32
|
||||
101..150 'for (e... }': fn into_iter<[(i32, i32); 1]>([(i32, i32); 1]) -> <[(i32, i32); 1] as IntoIterator>::IntoIter
|
||||
101..150 'for (e... }': IntoIter<(i32, i32), 1>
|
||||
101..150 'for (e... }': !
|
||||
101..150 'for (e... }': IntoIter<(i32, i32), 1>
|
||||
101..150 'for (e... }': &'? mut IntoIter<(i32, i32), 1>
|
||||
101..150 'for (e... }': fn next<IntoIter<(i32, i32), 1>>(&'? mut IntoIter<(i32, i32), 1>) -> Option<<IntoIter<(i32, i32), 1> as Iterator>::Item>
|
||||
101..150 'for (e... }': Option<(i32, i32)>
|
||||
101..150 'for (e... }': ()
|
||||
101..150 'for (e... }': ()
|
||||
101..150 'for (e... }': ()
|
||||
101..150 'for (e... }': ()
|
||||
105..111 '(e, f)': (i32, i32)
|
||||
106..107 'e': i32
|
||||
109..110 'f': i32
|
||||
115..123 '[(0, 1)]': [(i32, i32); 1]
|
||||
116..122 '(0, 1)': (i32, i32)
|
||||
117..118 '0': i32
|
||||
120..121 '1': i32
|
||||
124..150 '{ ... }': ()
|
||||
138..139 'g': i32
|
||||
142..143 'e': i32
|
||||
156..203 'if let... }': ()
|
||||
159..174 'let [val] = [y]': bool
|
||||
163..168 '[val]': [&'? i32; 1]
|
||||
164..167 'val': &'? i32
|
||||
171..174 '[y]': [&'? i32; 1]
|
||||
172..173 'y': &'? i32
|
||||
175..203 '{ ... }': ()
|
||||
189..190 'h': &'? i32
|
||||
193..196 'val': &'? i32
|
||||
209..235 'if let...rue {}': ()
|
||||
212..232 'let x ... &true': bool
|
||||
216..224 'x @ true': &'? bool
|
||||
220..224 'true': bool
|
||||
220..224 'true': bool
|
||||
227..232 '&true': &'? bool
|
||||
228..232 'true': bool
|
||||
233..235 '{}': ()
|
||||
245..251 'lambda': impl Fn(u64, u64, i32) -> i32
|
||||
254..286 '|a: u6...b; c }': impl Fn(u64, u64, i32) -> i32
|
||||
255..256 'a': u64
|
||||
263..264 'b': u64
|
||||
266..267 'c': i32
|
||||
274..286 '{ a + b; c }': i32
|
||||
276..277 'a': u64
|
||||
276..281 'a + b': u64
|
||||
280..281 'b': u64
|
||||
283..284 'c': i32
|
||||
297..309 'ref ref_to_x': &'? &'? i32
|
||||
312..313 'x': &'? i32
|
||||
323..332 'mut mut_x': &'? i32
|
||||
335..336 'x': &'? i32
|
||||
346..366 'ref mu...f_to_x': &'? mut &'? i32
|
||||
369..370 'x': &'? i32
|
||||
380..381 'k': &'? mut &'? i32
|
||||
384..396 'mut_ref_to_x': &'? mut &'? i32
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
|
@ -380,7 +384,7 @@ fn infer_pattern_match_string_literal() {
|
|||
fn infer_pattern_match_byte_string_literal() {
|
||||
check_infer_with_mismatches(
|
||||
r#"
|
||||
//- minicore: index
|
||||
//- minicore: index, range
|
||||
struct S;
|
||||
impl<T, const N: usize> core::ops::Index<S> for [T; N] {
|
||||
type Output = [u8];
|
||||
|
|
@ -395,7 +399,7 @@ fn infer_pattern_match_byte_string_literal() {
|
|||
"#,
|
||||
expect![[r#"
|
||||
105..109 'self': &'? [T; N]
|
||||
111..116 'index': {unknown}
|
||||
111..116 'index': RangeFull
|
||||
157..180 '{ ... }': &'? [u8]
|
||||
167..174 'loop {}': !
|
||||
172..174 '{}': ()
|
||||
|
|
|
|||
|
|
@ -64,20 +64,37 @@ fn type_alias_in_struct_lit() {
|
|||
|
||||
#[test]
|
||||
fn infer_ranges() {
|
||||
check_types(
|
||||
check_no_mismatches(
|
||||
r#"
|
||||
//- minicore: range
|
||||
fn test() {
|
||||
let a = ..;
|
||||
let b = 1..;
|
||||
let c = ..2u32;
|
||||
let d = 1..2usize;
|
||||
let e = ..=10;
|
||||
let f = 'a'..='z';
|
||||
//- minicore: range, new_range
|
||||
|
||||
let t = (a, b, c, d, e, f);
|
||||
t;
|
||||
} //^ (RangeFull, RangeFrom<i32>, RangeTo<u32>, Range<usize>, RangeToInclusive<i32>, RangeInclusive<char>)
|
||||
fn test() {
|
||||
let _: core::ops::RangeFull = ..;
|
||||
let _: core::ops::RangeFrom<i32> = 1..;
|
||||
let _: core::ops::RangeTo<u32> = ..2u32;
|
||||
let _: core::ops::Range<usize> = 1..2usize;
|
||||
let _: core::ops::RangeToInclusive<i32> = ..=10;
|
||||
let _: core::ops::RangeInclusive<char> = 'a'..='z';
|
||||
}
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn infer_ranges_new_range() {
|
||||
check_no_mismatches(
|
||||
r#"
|
||||
//- minicore: range, new_range
|
||||
#![feature(new_range)]
|
||||
|
||||
fn test() {
|
||||
let _: core::ops::RangeFull = ..;
|
||||
let _: core::range::RangeFrom<i32> = 1..;
|
||||
let _: core::ops::RangeTo<u32> = ..2u32;
|
||||
let _: core::range::Range<usize> = 1..2usize;
|
||||
let _: core::range::RangeToInclusive<i32> = ..=10;
|
||||
let _: core::range::RangeInclusive<char> = 'a'..='z';
|
||||
}
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -532,18 +532,12 @@ impl<'db> SourceAnalyzer<'db> {
|
|||
db: &'db dyn HirDatabase,
|
||||
range_pat: &ast::RangePat,
|
||||
) -> Option<StructId> {
|
||||
let path: ModPath = match (range_pat.op_kind()?, range_pat.start(), range_pat.end()) {
|
||||
(RangeOp::Exclusive, None, Some(_)) => path![core::ops::RangeTo],
|
||||
(RangeOp::Exclusive, Some(_), None) => path![core::ops::RangeFrom],
|
||||
(RangeOp::Exclusive, Some(_), Some(_)) => path![core::ops::Range],
|
||||
(RangeOp::Inclusive, None, Some(_)) => path![core::ops::RangeToInclusive],
|
||||
(RangeOp::Inclusive, Some(_), Some(_)) => path![core::ops::RangeInclusive],
|
||||
|
||||
(RangeOp::Exclusive, None, None) => return None,
|
||||
(RangeOp::Inclusive, None, None) => return None,
|
||||
(RangeOp::Inclusive, Some(_), None) => return None,
|
||||
};
|
||||
self.resolver.resolve_known_struct(db, &path)
|
||||
self.resolve_range_struct(
|
||||
db,
|
||||
range_pat.op_kind()?,
|
||||
range_pat.start().is_some(),
|
||||
range_pat.end().is_some(),
|
||||
)
|
||||
}
|
||||
|
||||
pub(crate) fn resolve_range_expr(
|
||||
|
|
@ -551,19 +545,59 @@ impl<'db> SourceAnalyzer<'db> {
|
|||
db: &'db dyn HirDatabase,
|
||||
range_expr: &ast::RangeExpr,
|
||||
) -> Option<StructId> {
|
||||
let path: ModPath = match (range_expr.op_kind()?, range_expr.start(), range_expr.end()) {
|
||||
(RangeOp::Exclusive, None, None) => path![core::ops::RangeFull],
|
||||
(RangeOp::Exclusive, None, Some(_)) => path![core::ops::RangeTo],
|
||||
(RangeOp::Exclusive, Some(_), None) => path![core::ops::RangeFrom],
|
||||
(RangeOp::Exclusive, Some(_), Some(_)) => path![core::ops::Range],
|
||||
(RangeOp::Inclusive, None, Some(_)) => path![core::ops::RangeToInclusive],
|
||||
(RangeOp::Inclusive, Some(_), Some(_)) => path![core::ops::RangeInclusive],
|
||||
self.resolve_range_struct(
|
||||
db,
|
||||
range_expr.op_kind()?,
|
||||
range_expr.start().is_some(),
|
||||
range_expr.end().is_some(),
|
||||
)
|
||||
}
|
||||
|
||||
fn resolve_range_struct(
|
||||
&self,
|
||||
db: &'db dyn HirDatabase,
|
||||
op_kind: RangeOp,
|
||||
has_start: bool,
|
||||
has_end: bool,
|
||||
) -> Option<StructId> {
|
||||
let has_new_range =
|
||||
self.resolver.top_level_def_map().is_unstable_feature_enabled(&sym::new_range);
|
||||
let lang_items = self.lang_items(db);
|
||||
match (op_kind, has_start, has_end) {
|
||||
(RangeOp::Exclusive, false, false) => lang_items.RangeFull,
|
||||
(RangeOp::Exclusive, false, true) => lang_items.RangeTo,
|
||||
(RangeOp::Exclusive, true, false) => {
|
||||
if has_new_range {
|
||||
lang_items.RangeFromCopy
|
||||
} else {
|
||||
lang_items.RangeFrom
|
||||
}
|
||||
}
|
||||
(RangeOp::Exclusive, true, true) => {
|
||||
if has_new_range {
|
||||
lang_items.RangeCopy
|
||||
} else {
|
||||
lang_items.Range
|
||||
}
|
||||
}
|
||||
(RangeOp::Inclusive, false, true) => {
|
||||
if has_new_range {
|
||||
lang_items.RangeToInclusiveCopy
|
||||
} else {
|
||||
lang_items.RangeToInclusive
|
||||
}
|
||||
}
|
||||
(RangeOp::Inclusive, true, true) => {
|
||||
if has_new_range {
|
||||
lang_items.RangeInclusiveCopy
|
||||
} else {
|
||||
lang_items.RangeInclusiveStruct
|
||||
}
|
||||
}
|
||||
// [E0586] inclusive ranges must be bounded at the end
|
||||
(RangeOp::Inclusive, None, None) => return None,
|
||||
(RangeOp::Inclusive, Some(_), None) => return None,
|
||||
};
|
||||
self.resolver.resolve_known_struct(db, &path)
|
||||
(RangeOp::Inclusive, false, false) => None,
|
||||
(RangeOp::Inclusive, true, false) => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn resolve_await_to_poll(
|
||||
|
|
|
|||
|
|
@ -526,6 +526,12 @@ define_symbols! {
|
|||
arbitrary_self_types,
|
||||
arbitrary_self_types_pointers,
|
||||
supertrait_item_shadowing,
|
||||
new_range,
|
||||
range,
|
||||
RangeCopy,
|
||||
RangeFromCopy,
|
||||
RangeInclusiveCopy,
|
||||
RangeToInclusiveCopy,
|
||||
hash,
|
||||
partial_cmp,
|
||||
cmp,
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@
|
|||
//! pin:
|
||||
//! pointee: copy, send, sync, ord, hash, unpin, phantom_data
|
||||
//! range:
|
||||
//! new_range:
|
||||
//! receiver: deref
|
||||
//! result:
|
||||
//! send: sized
|
||||
|
|
@ -175,7 +176,9 @@ pub mod marker {
|
|||
|
||||
// region:clone
|
||||
impl<T: PointeeSized> Clone for PhantomData<T> {
|
||||
fn clone(&self) -> Self { Self }
|
||||
fn clone(&self) -> Self {
|
||||
Self
|
||||
}
|
||||
}
|
||||
// endregion:clone
|
||||
|
||||
|
|
@ -1128,6 +1131,32 @@ pub mod ops {
|
|||
// endregion:dispatch_from_dyn
|
||||
}
|
||||
|
||||
// region:new_range
|
||||
pub mod range {
|
||||
#[lang = "RangeCopy"]
|
||||
pub struct Range<Idx> {
|
||||
pub start: Idx,
|
||||
pub end: Idx,
|
||||
}
|
||||
|
||||
#[lang = "RangeFromCopy"]
|
||||
pub struct RangeFrom<Idx> {
|
||||
pub start: Idx,
|
||||
}
|
||||
|
||||
#[lang = "RangeInclusiveCopy"]
|
||||
pub struct RangeInclusive<Idx> {
|
||||
pub start: Idx,
|
||||
pub end: Idx,
|
||||
}
|
||||
|
||||
#[lang = "RangeToInclusiveCopy"]
|
||||
pub struct RangeToInclusive<Idx> {
|
||||
pub end: Idx,
|
||||
}
|
||||
}
|
||||
// endregion:new_range
|
||||
|
||||
// region:eq
|
||||
pub mod cmp {
|
||||
use crate::marker::PointeeSized;
|
||||
|
|
@ -1144,7 +1173,9 @@ pub mod cmp {
|
|||
|
||||
// region:builtin_impls
|
||||
impl PartialEq for () {
|
||||
fn eq(&self, other: &()) -> bool { true }
|
||||
fn eq(&self, other: &()) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
// endregion:builtin_impls
|
||||
|
||||
|
|
@ -1567,10 +1598,7 @@ pub mod pin {
|
|||
}
|
||||
// endregion:dispatch_from_dyn
|
||||
// region:coerce_unsized
|
||||
impl<Ptr, U> crate::ops::CoerceUnsized<Pin<U>> for Pin<Ptr> where
|
||||
Ptr: crate::ops::CoerceUnsized<U>
|
||||
{
|
||||
}
|
||||
impl<Ptr, U> crate::ops::CoerceUnsized<Pin<U>> for Pin<Ptr> where Ptr: crate::ops::CoerceUnsized<U> {}
|
||||
// endregion:coerce_unsized
|
||||
}
|
||||
// endregion:pin
|
||||
|
|
@ -1792,9 +1820,9 @@ pub mod iter {
|
|||
fn from_iter<T: IntoIterator<Item = A>>(iter: T) -> Self;
|
||||
}
|
||||
}
|
||||
pub use self::collect::{IntoIterator, FromIterator};
|
||||
pub use self::collect::{FromIterator, IntoIterator};
|
||||
}
|
||||
pub use self::traits::{IntoIterator, FromIterator, Iterator};
|
||||
pub use self::traits::{FromIterator, IntoIterator, Iterator};
|
||||
}
|
||||
// endregion:iterator
|
||||
|
||||
|
|
@ -2091,30 +2119,30 @@ macro_rules! column {
|
|||
pub mod prelude {
|
||||
pub mod v1 {
|
||||
pub use crate::{
|
||||
clone::Clone, // :clone
|
||||
cmp::{Eq, PartialEq}, // :eq
|
||||
cmp::{Ord, PartialOrd}, // :ord
|
||||
convert::AsMut, // :as_mut
|
||||
convert::AsRef, // :as_ref
|
||||
convert::{From, Into, TryFrom, TryInto}, // :from
|
||||
default::Default, // :default
|
||||
iter::{IntoIterator, Iterator, FromIterator}, // :iterator
|
||||
macros::builtin::{derive, derive_const}, // :derive
|
||||
marker::Copy, // :copy
|
||||
marker::Send, // :send
|
||||
marker::Sized, // :sized
|
||||
marker::Sync, // :sync
|
||||
mem::drop, // :drop
|
||||
mem::size_of, // :size_of
|
||||
ops::Drop, // :drop
|
||||
ops::{AsyncFn, AsyncFnMut, AsyncFnOnce}, // :async_fn
|
||||
ops::{Fn, FnMut, FnOnce}, // :fn
|
||||
option::Option::{self, None, Some}, // :option
|
||||
panic, // :panic
|
||||
result::Result::{self, Err, Ok}, // :result
|
||||
str::FromStr, // :str
|
||||
fmt::derive::Debug, // :fmt, derive
|
||||
hash::derive::Hash, // :hash, derive
|
||||
clone::Clone, // :clone
|
||||
cmp::{Eq, PartialEq}, // :eq
|
||||
cmp::{Ord, PartialOrd}, // :ord
|
||||
convert::AsMut, // :as_mut
|
||||
convert::AsRef, // :as_ref
|
||||
convert::{From, Into, TryFrom, TryInto}, // :from
|
||||
default::Default, // :default
|
||||
fmt::derive::Debug, // :fmt, derive
|
||||
hash::derive::Hash, // :hash, derive
|
||||
iter::{FromIterator, IntoIterator, Iterator}, // :iterator
|
||||
macros::builtin::{derive, derive_const}, // :derive
|
||||
marker::Copy, // :copy
|
||||
marker::Send, // :send
|
||||
marker::Sized, // :sized
|
||||
marker::Sync, // :sync
|
||||
mem::drop, // :drop
|
||||
mem::size_of, // :size_of
|
||||
ops::Drop, // :drop
|
||||
ops::{AsyncFn, AsyncFnMut, AsyncFnOnce}, // :async_fn
|
||||
ops::{Fn, FnMut, FnOnce}, // :fn
|
||||
option::Option::{self, None, Some}, // :option
|
||||
panic, // :panic
|
||||
result::Result::{self, Err, Ok}, // :result
|
||||
str::FromStr, // :str
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue