์ด๊ฒ์ ์ผ๋ฐ ๊ด๋ จ ์ ํ์ ๋ํ ์ถ์ ๋ฌธ์ ์ ๋๋ค(rust-lang/rfcs#1598).
ํ ๊ฒ:
๋ค์์ ์ ๋ฐ์ดํธ๋ฅผ ์ ์งํ๊ธฐ ์ํด ๋ ธ๋ ฅํ ์ผ์ข ์ ๊ตฌํ ๊ณํ์ ๋๋ค.
AST์ ๋ํด ๋ ์์ธํ ์์ฑํ๋ ๊ฒ์ผ๋ก ์์ํ๊ฒ ์ต๋๋ค. ๋จผ์ ์ค๋ ์๋ ๋ฐฉ์์ ๋ํด ๋ ผ์ํด ๋ณด๊ฒ ์ต๋๋ค.
ํน์ฑ ์ ์์ type Foo: Bar [= Baz];
ํญ๋ชฉ์ ์ด AST ๋ณํ ์ ์ํด ์ ์๋ฉ๋๋ค. ์ฌ๊ธฐ์๋ ๊ฒฝ๊ณ( Bar
)์ (์ ํ ์ฌํญ) ๊ธฐ๋ณธ๊ฐ Baz
๊ฐ ํฌํจ๋ฉ๋๋ค. ์ด๋ฆ์ TraitItem
๊ตฌ์กฐ์ฒด ์ ์ ์๋์ด ์์ต๋๋ค.
ํน์ฑ impl์ type Foo = Bar;
ํญ๋ชฉ์ ์ด AST ๋ณํ ์ ์ํด ์ ์๋ฉ๋๋ค. Foo
๋ฑ์ด ImplItem
์ ์ ์๋์ด ์๊ธฐ ๋๋ฌธ์ Bar
์ ํ๋ง ํฌํจํฉ๋๋ค. ImplItem
๊ตฌ์กฐ์ฒด .
๋ฉ์๋๋ ์ด๋ฏธ ์ผ๋ฐํ๋ ์ ์๊ธฐ ๋๋ฌธ์ ํฅ๋ฏธ๋ก์ด ๊ฒฝ์ฐ์
๋๋ค. ์ด๋ฌํ ์ผ๋ฐ ๋งค๊ฐ๋ณ์๋ MethodSig
๊ตฌ์กฐ์ Generics
ํ๋ ์ ์ ์ธ๋ฉ๋๋ค. ์ด๊ฒ์ Generics
๊ตฌ์กฐ์ฒด ์ ์ธ์คํด์ค์
๋๋ค.
๋ด ์๊ฐ์ ๊ฐ์ฅ ์ข์ ๋ฐฉ๋ฒ์ Generics
๋ฉ์๋ ์์ TraitItem
(๋ฐ ImplItem
)๋ก "๋ค์ด์ฌ๋ ค" ๋ชจ๋ ํ์์ ๋์ผํ๊ฒ ์ ์ฉ๋๋๋ก ํ๋ ๊ฒ์
๋๋ค. ํน์ฑ ๋ฐ ์ํ ํญ๋ชฉ. ์ง๊ธ์ผ๋ก์๋ ์ผ๋ฐ ์์๋ฅผ ์ง์ํ์ง ์์ ๊ฒ ๊ฐ์ต๋๋ค. ํ์ง๋ง ์์งํ ๋งํด์ ์ด ์์๋ ์ด๋ค ๊ฒฝ์ฐ์๋ ์ฐ๋ฆฌ๊ฐ ํ๊ณ ์๋ ์์
์์ ๋น ์ง ์ ์์ผ๋ฏ๋ก ์์ ํ์ฅ์ด ๋ ๊ฒ์
๋๋ค. ์ง๊ธ ๊ณํ๋ง ํ๋ฉด ์์
์ด ๋ ์ ๋ ๊ฒ ๊ฐ์์.
์๋ง๋ ๊ด์ฐฎ์ ์ฒซ ๋ฒ์งธ PR์ ๊ทธ ๋ณ๊ฒฝ์ ์ํํ๊ณ ๋ค๋ฅธ ๋ชจ๋ ๊ธฐ์กด ๊ธฐ๋ฅ์ ๋์ผํ๊ฒ ์ ์งํ๋ ๊ฒ์
๋๋ค. ์ฆ, Generics
๋ฅผ TraitItem
(๋ฐ ImplItem
) ๋ฐ MethodSig
์์ ์ถ๊ฐํฉ๋๋ค. ๋ฉ์๋๊ฐ ์๋ ๊ฒฝ์ฐ์๋ ๋น Generics
๋ฅผ ์ ๊ณตํฉ๋๋ค. ์ฐ๋ฆฌ๋ ๊ธฐ์กด ์ฝ๋๋ฅผ ํตํด ์์
ํ๊ณ ์ ๋ค๋ฆญ์ด ์๋ํ๋๋ก ํ์์ ๋ฐ๋ผ ์ฐ๊ฒฐํฉ๋๋ค.
@nikomatsakis ๋ฉ์ง๋ค! ์ ๋ง ๊ณ ๋ง์ต๋๋ค! ๋๋ ์ด์ ฏ๋ฐค์ ์ด๊ฒ์ ์คํํ๊ธฐ ์์ํ๊ณ ๋๋ ๋น์ ์ด AST์ ๋ํ ๋น์ ์ ๋ ผํ์์ ์ง์ ํ ๊ฒ๊ณผ ๊ฐ์ ๊ณณ์ ์ฐพ์๋ค๋ ๊ฒ์ ์๋์ค๋ฝ๊ฒ ์๊ฐํฉ๋๋ค. :smile: (rusc์์ ์ฒ์ ํด๋ณด๋๊ฑฐ๋ผ์ ์ฑ์ทจ๊ฐ์ด ํฝ๋๋ค!)
์ ๋ค๋ฆญ์ TraitItem
๋ก ์ฌ๋ฆด ์๊ฐ์ ํ์ง ์์์ต๋๋ค. ๋ด ์ ๊ทผ ๋ฐฉ์์ Generics
๋ฅผ TraitItemKind::Type
์ ๋ฃ๋ ๊ฒ์ด์์ต๋๋ค. ์๋ํ๋ฉด ๊ฑฐ๊ธฐ์ ์ ํ ์ ์ธ์ด ์ด๋ฏธ ์ ์ฅ๋์ด ์๊ธฐ ๋๋ฌธ์
๋๋ค. ๊ทํ์ ์ ๊ทผ ๋ฐฉ์๋ ์๋ฏธ๊ฐ ์์ผ๋ฏ๋ก ๊ตฌํํ๊ธฐ ์ํด ๋
ธ๋ ฅํ๊ฒ ์ต๋๋ค. ๋๋ ์ด ์ฝ๋๋ฒ ์ด์ค์ ๋ํด ์์ ํ ์๋ก์ด ์ฌ๋์ด๊ธฐ ๋๋ฌธ์ ๋น์ ์ด ์ ์ํ ๊ฒ๋ณด๋ค ์ฌ์ฉํ๋ค๋ฉด ๋ด ์ ๊ทผ ๋ฐฉ์์ ํจ์ ์ด ๋ฌด์์ธ์ง ์๊ณ ์ถ์ต๋๋ค. ๋น์ ์ ์ฌ๊ณ ๊ณผ์ ์ ๋ํ ํต์ฐฐ๋ ฅ์ ์ค ์ ์์ต๋๊น? : ์ค๋ง์ผ :
๋ค์์ ๋ด๊ฐ ๋ณ๊ฒฝํ์ ๊ฒ์ ๋๋ค.
pub enum TraitItemKind {
// Generics aren't supported here yet
Const(P<Ty>, Option<P<Expr>>),
// `Generics` is already a field in `MethodSig`
Method(MethodSig, Option<P<Block>>),
// Added `Generics` here:
Type(Generics, TyParamBounds, Option<P<Ty>>),
Macro(Mac),
}
ํธ์ง: Gitter์์ nikomatsakis์ ๋ต๋ณ
๊ทธ๊ฒ๋ค์ ์ ํ์ ๋ฃ๋ ๊ฒ์ ํจ์ ์ ๊ดํ์ฌ
๋๋ ๊ทธ๊ฒ์ด ํจ๊ณผ๊ฐ ์์ ์ ์๋ค๊ณ ์๊ฐํ๋ค
๋ด๊ฐ ๊ทธ๊ฒ์ ๊บผ๋ คํ๋ ์ด์
๋ฐฉ๋ฒ๊ณผ ์ ํ์ ๋ํด (์ ์ด๋ ์ด๋ก ์์ผ๋ก๋) ๋์ผํ ์์ ์ ์ํํ๊ธฐ๋ฅผ ์ ๋ง๋ก ์ํ๋ค๋ ๊ฒ์ ๋๋ค.
๊ทธ๋ฆฌ๊ณ -- ๋ด๊ฐ ๋งํ๋ฏ์ด -- ์์น์ ์ผ๋ก ์ฐ๋ฆฌ๊ฐ ์์์ ๋ํด ๊ฐ์ ์ผ์ ํ ์ ์์ ์ด์ ๊ฐ ์๋ค๊ณ ์๊ฐํฉ๋๋ค.
์ ๋ค๋ฆญ์ ์ ํ ๋ณํ์ผ๋ก ์ฎ๊ธฐ๋ฉด
๊ทธ๊ฒ์ ์๋ง๋ ๊ด์ฐฎ์ ๊ฒ์ ๋๋ค. ํ์ง๋ง ์ง๊ธ์ "์ ํ/์์์ ๋ํด ํ ๊ฐ์ง, ๋ฉ์๋์ ๋ํด ํ ๊ฐ์ง"๋ฅผ ์ํํด์ผ ํ๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ต๋๋ค. ์ ํํ ๋ค๋ฅด๊ธฐ ๋๋ฌธ์ ๋๋ค.
๊ทธ๋์ ๋๋ ์ฝ๋๊ฐ ๋ ๊ท ์ผํด์ง ๊ฒ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค.
์์งํ ์ด๋ป๊ฒ ๋ ์ง ์ ๋ชจ๋ฅด๊ฒ ์ต๋๋ค =) -- ๊ณ ํต์ค๋ฌ์ธ ์ ์์ต๋๋ค
ํ์ง๋ง ํ์ํ ๊ฒ๋ณด๋ค ๋ ์ผ๋ฐ์ ์ธ ๊ฒ์ ๊ฐ๋ ๊ฒ์ด ๊ทธ๋ ๊ฒ ๋์์ง๋ ์์ ๊ฒฝ์ฐ๊ฐ ๋ง์ต๋๋ค. ์๋ํ๋ฉด ๋น์ ์ด span_bug๋ฅผ ์ฝ์ ํ ์ ์๊ธฐ ๋๋ฌธ์ ๋๋ค! ์ง๊ธ์ ๋ถ๊ฐ๋ฅํ ๊ฒฝ์ฐ๋ฅผ ์์ฒญํฉ๋๋ค(๋์ค์ ์์ ํจ์นํฉ๋๋ค)
๊ด์ฐฎ์! ๋ค์ ๋จ๊ณ๋ ํ์๋ฅผ ํ์ฅํ๋ ๊ฒ์ ๋๋ค. ๋ค์์ ๋ช ๊ฐ์ง ํ์ ๋๋ค. ํน์ฑ ํญ๋ชฉ๋ถํฐ ์์ํ๊ฒ ์ต๋๋ค.
์ด ๋ฃจํด์ ํน์ฑ ํญ๋ชฉ์ ๊ตฌ๋ฌธ ๋ถ์ํฉ๋๋ค . ์ฐ๋ฆฌ๋ type Foo<....> = ...;
(์ด์ฉ๋ฉด where-clauses)์ ๊ฐ์ ๊ฒ๋ค์ ๊ตฌ๋ฌธ ๋ถ์ํ๊ธฐ ์ํด ์ฐ๊ด๋ ์ ํ์ ์ฒ๋ฆฌํ๋ ์ผ์ด์ค ๋ฅผ ํ์ฅํ๊ณ ์ ํฉ๋๋ค. ( <...>
๋ ๋ฐฉ๊ธ AST์ ์ถ๊ฐํ "์ ๋ค๋ฆญ"์
๋๋ค.)
ํ์ฌ ๊ธฐ๋ณธ์ ์ผ๋ก T: Foo
๋ฑ๊ณผ ๊ฐ์ ๊ฒ์ ๊ตฌ๋ฌธ ๋ถ์ํ๋ parse_ty_param
๋ฅผ ์ฌ์ฉํ๊ณ ์์ต๋๋ค. ์ฐ๊ด๋ ์ ํ ์ ์ธ์ ๋ฌธ๋ฒ์ด ๋ ์ด์ ์ ํ ๋งค๊ฐ๋ณ์์ ๋ฌธ๋ฒ๊ณผ ์ผ์นํ์ง ์๊ธฐ ๋๋ฌธ์ ์ด ์์
์ ์ค๋จํด์ผ ํฉ๋๋ค. ๋ฐ๋ผ์ parse_trait_item_assoc_ty
์ ๊ฐ์ ๊ฒ์ ์ถ๊ฐํ๊ณ ์ถ์ ๊ฒ์
๋๋ค. ์ด๊ฒ์ parse_ty_param()
์ ๋ณต์ ๋ก ์์ํ ์ ์์ง๋ง ๋ฐ๋ก ์ฌ๊ธฐ์์ parse_generics()
๋ฅผ ํธ์ถ ํ๋๋ก ์์ ํด์ผ ํฉ๋๋ค. ํด๋น ๋ฃจํด์ ์ ๋ค๋ฆญ ์ ์ธ( <...>
)์ด ์์ผ๋ฉด ์ด๋ฅผ ๊ตฌ๋ฌธ ๋ถ์ํ๊ณ , ๊ทธ๋ ์ง ์์ผ๋ฉด ๋น ์ ๋ค๋ฆญ์ ๋ฐํํฉ๋๋ค. ๊ทธ๋ฐ ๋ค์ ๋ฐ๋ก ์ฌ๊ธฐ ์ where ์ ์ ๊ตฌ๋ฌธ ๋ถ์ํ๋ ํธ์ถ์ ์ถ๊ฐํ๊ณ ์ถ์ต๋๋ค. ๋ฉ์๋๋ฅผ ๊ตฌ๋ฌธ ๋ถ์ํ ๋ ๋ฐ์ํ๋ ํธ์ถ์ ๋ชจ๋ธ๋งํ ์ ์์ต๋๋ค. ๊ฒฐ๊ณผ๋ ์ด์ ์ ๊ตฌ๋ฌธ ๋ถ์ํ generics
์ ์ ์ฅ๋ฉ๋๋ค.
๊ทธ๋ ๊ฒ ํ๊ณ ๋๋ฉด ๋ช ๊ฐ์ง ๊ตฌ๋ฌธ ๋ถ์ ํ
์คํธ๋ฅผ ์ถ๊ฐํ ์ ์์ด์ผ ํฉ๋๋ค. src/test/run-pass/rfc1598-generic-associated-types/
์ ๊ฐ์ ๋๋ ํ ๋ฆฌ๋ฅผ ๋ง๋ค๊ณ ๊ฑฐ๊ธฐ์ ์ฑ๊ณต์ ์ผ๋ก ๊ตฌ๋ฌธ ๋ถ์ํ ๊ฒ์ผ๋ก ์์๋๋ ํ์ผ์ ์ถ๊ฐํ๋ฉด ๋ฉ๋๋ค. ์ง๊ธ์ ์ ๋๋ก ์๋ ํ์ง ์์ง๋ง ๊ทธ๊ฒ์ ์ค์ํ์ง ์์ต๋๋ค. ๋น ๋ฉ์ธ ํจ์๋ฅผ ์ถ๊ฐํ๊ธฐ๋ง ํ๋ฉด ๋ฉ๋๋ค. ๊ทธ๋ฐ ๋ค์ src/test/ui/rfc1598-generic-associated-types/
๋ก ๊ตฌ๋ฌธ ๋ถ์ํด์๋ ์ ๋๋ ์์ ๋ฅผ ์ถ๊ฐํ ์๋ ์์ต๋๋ค( UI ํ
์คํธ ์ถ๊ฐ์ ๋ํ ์ง์นจ์ COMPILER_TESTS.md
์ฐธ์กฐ).
๋ค๋ฅธ ๊ฒ -- ์ฌ๋๋ค์ด ์์ ์ ์ธ ๋น๋์์ ์ด ํญ๋ชฉ์ ์ฌ์ฉํ์ง ์๋๋ก ์ด ์์ ์์ ๊ฒ์ดํธ ๊ธฐ๋ฅ์ ์ ๊ณตํด์ผ ํฉ๋๋ค. ์ฌ๊ธฐ forge์ ๊ธฐ๋ฅ ๊ฒ์ดํธ๋ฅผ ์ถ๊ฐ ํ๊ธฐ ์ํ ๋ช ๊ฐ์ง ์ง์นจ์ด ์์ต๋๋ค(๋ง์ง๋ง ์น์
์ฐธ์กฐ). feature_gate.rs
์ ๋ฐฉ๋ฌธ์ ์๊ฒ visit_trait_item
๋ฐ visit_impl_item
๋ฅผ ์ถ๊ฐํด์ผ ํฉ๋๋ค. ํด๋น ํญ๋ชฉ์ด ๋ฉ์๋๊ฐ ์๋์ง๋ง ๋น์ด ์์ง ์์ ์ ๋ค๋ฆญ์ด ์๋ ๊ฒฝ์ฐ gate_feature_post
( ์์ )๋ฅผ ํธ์ถํ ์ ์์ต๋๋ค.
์ด๋ฆ ํ์ธ์ ์ค์ ํ๊ธฐ ์ํด ์ฐ๋ฆฌ๊ฐ ํด์ผ ํ ์ผ์ ์ ์ ํ "๊ฐ๋น๋ผ"๋ฅผ ์ ์๋ฆฌ์ ๋๋ ๊ฒ๋ฟ์ด๋ผ๊ณ ์๊ฐ ํฉ๋๋ค(์ด๋ฆ ํ์ธ ํญ๋ชฉ์ ๋ฒ์์ ์๋ ์ด๋ฆ ์งํฉ์ ๊ฐ๋น๋ผ๋ก ๊ตฌ์ฑํฉ๋๋ค. ๊ฐ ๊ฐ๋น๋ ํ๋์ ๋ฐ์ธ๋ฉ ์์ค์ ๋ํ๋). ์๋ฅผ ๋ค์ด impl์ ๊ฒฝ์ฐ:
impl<A,B> Foo<B> for Vec<A> {
fn bar<T,U>(x: ...) {
for y in ... {
}
}
}
์ฐ๋ฆฌ๋ ๋ค์๊ณผ ๊ฐ์ ๊ฐ๋น๋ผ๋ฅผ ๊ฐ์ง ๊ฒ์ ๋๋ค:
- <A,B> (from the impl)
- <T,U> (from the `bar` method's generics)
- `x` (from the parameter list)
- `y` (from the let)
์ผ๋ฐ์ ์ผ๋ก ๋ฐฉ๋ฒ์ด ์๋ํ๋ ๋ฐฉ์์ ๋ชจ๋ธ๋งํ๋ ๊ฒ์ ๋์ ์๊ฐ์ด ์๋๋๋ค. ์ฌ๊ธฐ์์ ์ฝ๊ฐ์ "๋ฏธ๋ ๊ฒ์ฆ"์ ํ ์๋ ์์ต๋๋ค.
๋ค์์ ๋ฉ์๋์ ์ ํ ๋งค๊ฐ๋ณ์๋ฅผ ๋ฒ์๋ก ๊ฐ์ ธ์ค๋ ์ฝ๋์ ๋๋ค(ํน์ฑ์ ์ ์๋ ๋ฉ์๋์ฉ).
๋ฐ๋ฉด์ ํน์ฑ์ ์ ์๋ type
์ ๊ฒฝ์ฐ ๋น ์ ํ ๋งค๊ฐ๋ณ์ rib( NoTypeParameters
)๋ฅผ ์ถ๊ฐํ๋๋ก ํ๋์ฝ๋ฉ๋ฉ๋๋ค.
์ด์ ์ ๋ค๋ฆญ์ด ๋ชจ๋ ํน์ฑ/impl ํญ๋ชฉ์ ๋ฐฐ์น๋์์ผ๋ฏ๋ก type
์ ๋ํ ์ฒ๋ฆฌ๋ฅผ ์ ๊ฑฐํ๊ณ ๋ ๋์ ์์ค์์ ๋ฐ์ํ๋๋ก ๋ฉ์๋ ์ฒ๋ฆฌ๋ฅผ ์ถ์ถํ๊ณ ์ถ์ต๋๋ค. ์ ๋ค๋ฆญ์ด ์๋ ํญ๋ชฉ(์: const
)์ ๊ฒฝ์ฐ ์๋ก ๋์
๋ ๋ฆฌ๋ธ๋ ๋น์ด ์์ด์ผ ํ๋ฏ๋ก ๋ฌดํดํด์ผ ํฉ๋๋ค(ํฌ๋งํฉ๋๋ค).
๋ค๋ฅธ ๊ด์ฌ ์ง์ :
๋น์ ์ ์์ด๋์ด๋ฅผ ์ป์.
@petrochenkov -- ์๋ฆฌ๊ฐ ๋ง๋์?
@nikomatsakis
๋ง๋ ์๋ฆฌ?
๋ชจ๋ ๊ฒ์ด ์ฌ๋ฐ๋ฅด๊ฒ ๋ณด์ ๋๋ค.
๋ค์ ๋จ๊ณ. ํ์ ํด์๋.
์ข๋ ๋์๋ , ์ด๊ฒ์ ํ์ฌ ๋ค๋ฅธ ์ด๋ฆ ํ์ธ๊ณผ ์์ ํ ๋ค๋ฅธ ์ฝ๋ ๋นํธ์์ ์ํ๋ฉ๋๋ค. ์ด๋ HIR์ด ๊ตฌ์ฑ๋ ํ์ ๋ฐ์ํ๊ธฐ ๋๋ฌธ์ ๋๋ค. ๊ฑฐ์ ํ์คํ ์ด๊ฒ์ ๋ณ๊ฒฝ๋์ง๋ง ์์ง ๋ณ๊ฒฝ๋์ง ์์์ต๋๋ค.
๊ธฐ๋ณธ์ ์ธ ๊ฐ๋ ์ ์ฐ๋ฆฌ๊ฐ ์ฌ๋ฌผ์ "๊ฐ๋น๋ผ"๋ผ๊ณ ๋ถ๋ฅด์ง ์๊ณ ์คํ๋ ค "๋ฒ์"๋ผ๊ณ ๋ถ๋ฅด๋ ๊ฒ์ ์ ์ธํ๊ณ ๋ ์ผ๋ฐ์ ์ธ ์ด๋ฆ ํ์ธ๊ณผ ๋์ผํฉ๋๋ค. =)
"๋ฆ์ ๋ฐ์ธ๋ฉ" ์๋ช ์ด๋ผ๋ ๊ฐ๋ ์ผ๋ก ์ธํด ์ฝ๊ฐ์ ํฉ๋ณ์ฆ์ด ์์ต๋๋ค. ์ฌ๊ธฐ์์๋ ์ค์ ๋ก ๊ด๋ จ์ด ์์ต๋๋ค. ์ ๋ค๋ฆญ ๊ด๋ จ ์ ํ์ ๋ชจ๋ ์๋ช ์ "์กฐ๊ธฐ ๋ฐ์ธ๋ฉ"๋๋ฉฐ, ์ด๋ ์ผ์ข ์ ๊ฐ๋จํ ๊ฒฝ์ฐ์ ๋๋ค. "๋ฆ์ ๊ฒฝ๊ณ" ์๋ช ์ ๋ฉ์๋๊ฐ ํธ์ถ๋ ๋๊น์ง ๊ฐ์ด ์ ๊ณต๋์ง ์๋ ๋ฉ์๋ ๋๋ ํจ์์ ์ ์ธ๋ ์๋ช ์ ๋๋ค. ์ฌ๊ธฐ์ ์ธ๋ถ ์ฌํญ์ ๋ค๋ฃจ์ง ์๊ฒ ์ต๋๋ค. ๊ด๋ จ์ฑ์ด ๋์ง ์๊ธฐ ๋๋ฌธ์ ๋๋ค. ์ค์ํ ๊ฒ์ ๋ค๋ฅธ ์ด๋ฆ ํ์ธ๊ณผ ๋ฌ๋ฆฌ ๋ค๋ฅธ ์ข ๋ฅ์ ์ผ๋ฐ ํญ๋ชฉ์ ๋ํด ์ํํ๋ ๊ฒ๊ณผ ๋์ผํ ๋ชจ๋ธ์ ๋ฉ์๋์ ๋ํด ์ ํํ ๋ฐ๋ฅด๊ณ ์ถ์ง ์๋ค๋ ๊ฒ์ ๋๋ค. ์ฌ๋ก.
๋ค์์ ์ฝ๋์ ์์
๋๋ค. impl
, struct
๋๋ ๊ธฐํ ๊ธฐ๋ฅ์ด ์๋ ํญ๋ชฉ์ ๋ฐฉ๋ฌธํ๋ ์ฝ๋์
๋๋ค. ์ด๋ฌํ ๊ฒฝ์ฐ GAT์์์ ๊ฐ์ด ๊ธฐ๋ณธ์ ์ผ๋ก Generics
์ ๋ชจ๋ ์๋ช
๋งค๊ฐ๋ณ์๋ฅผ ๋ฒ์๋ก ๊ฐ์ ธ์ "์กฐ๊ธฐ ๋ฐ์ธ๋ฉ๋" ์๋ช
์ ๋งคํํ๋ ค๊ณ ํฉ๋๋ค.
๋จผ์ ์๋ช
๋ฒกํฐ๋ฅผ ์์ฑํ๊ณ ๊ฐ๊ฐ์ ๋ํด Region::early
๋ฅผ ํธ์ถํ๋ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค.
๋ค์์ผ๋ก Scope
๋ฅผ ์์ฑํฉ๋๋ค. next_early_index
๋ณ์๋ ๋ฒ์์ ์๋ ์ด๊ธฐ ๋ฐ์ธ๋ฉ ์๋ช
์๋ฅผ ๊ณ์ฐํ๋ ๊ฒ์
๋๋ค. ์ด ์ฝ๋๋ ํญ๋ชฉ์๋ง ์ ์ฉ๋๋ฏ๋ก ํญ์ ํ์ฌ ํญ๋ชฉ์ ์ ์ธ๋ ์ด๊ธฐ ๋ฐ์ธ๋ฉ ์๋ช
์ ์๊ฐ ๋ฉ๋๋ค. (๋์ค์ ์ฐ๋ฆฌ๋ ์ถ๊ฐ ์๋ช
์ ๋ฒ์๋ก ๊ฐ์ ธ์ค๋ ๊ฒฝ์ฐ๋ฅผ ์ดํด๋ณผ ๊ฒ์
๋๋ค. ์ด๋ ์ฐ๋ฆฌ๊ฐ GAT์ ๋ ์ํ๋ ๊ฒ์
๋๋ค.)
๋ง์ง๋ง์ผ๋ก with()
๋ฅผ ํธ์ถํฉ๋๋ค. ์ด ๋ฉ์๋๋ ๋ฒ์๋ฅผ ๋ฒ์๋ก ๊ฐ์ ธ์ค๊ณ ํด๋ก์ ๋ฅผ ํธ์ถํฉ๋๋ค. ์ด ํด๋ก์ ๋ด์์ ๋ฐฉ๋ฌธํ๋ ๋ชจ๋ ์๋ช
์ ๋ฒ์๋ก ์ ์ํ ์ด๋ฆ์ ๋ณผ ์ ์์ต๋๋ค.
์, ์ด์ ์๋ฅผ ํ๋ ๋ ์ดํด๋ณด๊ฒ ์ต๋๋ค. ์ด ์ฌ๋ก๋ "impl ํน์ฑ"์ ๋ค๋ฃน๋๋ค. ๊ทธ๊ฒ์ด ํ๋ ์ผ์ ๋ํ ์ธ๋ถ ์ฌํญ์ ๊ทธ๋ ๊ฒ ์ค์ํ์ง ์์ต๋๋ค(์ฆ, impl Trait
๋์๊ฐ๋ง ์์ฒด๋ฅผ ์ํํ ํ์๊ฐ ์์ต๋๋ค). ์๋ก์ด ์ด๊ธฐ ๋ฐ์ธ๋ฉ ์๋ช
์ ๋ฒ์๋ก ๊ฐ์ ธ์ค๊ณ ์๋ค๊ณ ๋งํ๋ ๊ฒ์ผ๋ก ์ถฉ๋ถํฉ๋๋ค. ์ด๊ฒ์ด ๋ฐ๋ก ์ฐ๋ฆฌ๊ฐ GAT์ ๋ํด ์ํํ๋ ค๋ ๊ฒ์
๋๋ค.
๋ช ๊ฐ์ง๋ฅผ ๊ฐ์กฐํ๊ฒ ์ต๋๋ค. ๋จผ์ next_early_index
๋ฉ์๋๋ ํ ๋น๋์ง ์์ ๋ค์ ์ด๊ธฐ ๋ฐ์ธ๋ฉ ์ธ๋ฑ์ค๋ฅผ ๋ฐํํฉ๋๋ค.
๊ทธ๊ฒ์ ์ถ๋ฐ์ ์ ์ ๊ณตํฉ๋๋ค. ๋ค์์ผ๋ก Region::early
๋ฅผ ๋ค์ ์ฌ์ฉํ์ฌ ๋ค์์ ๋ํด ํด๊ฒฐ๋ ์๋ก์ด ์กฐ๊ธฐ ๋ฐ์ธ๋ฉ ์๋ช
์ ์๋ฅผ ๋ง๋ญ๋๋ค.
๋ง์ง๋ง์ผ๋ก with
๋ฅผ ๋ค์ ํธ์ถํ์ฌ ๋ฒ์๋ก ๊ฐ์ ธ์ต๋๋ค.
์ข์ต๋๋ค. ๋ ๊ฐ์ง ์์ ๋๋ค. ์ฐ๋ฆฌ๋ ๋ ๋ฒ์งธ ๊ฒ๊ณผ ๋น์ทํ ๊ฒ์ ํ๊ณ ์ถ์ ๊ฒ์ ๋๋ค. ์ด ๋ ๊ฐ์ง ๋ฐฉ๋ฒ์ ์ ์๋ฅผ ์์ ํ๋ ค๊ณ ํฉ๋๋ค.
๋ ๋ค ์ฐ๊ฒฐ๋ ์ ํ์ ๋ํด ์ฐ๊ฒฐ๋ ์ ๋ค๋ฆญ์ ์ฒ๋ฆฌํด์ผ ํฉ๋๋ค. (์๋ง๋ ๋ค๋ฅธ ๊ฒฝ์ฐ์๋ ์ ๋ค๋ฆญ์ด ๋น์ด ์๋ค๊ณ ์ฃผ์ฅํด์ผ ํฉ๋๋ค.)
๊ทธ๋์ ๋๋ ์ค๋ ์ผ์ฐ์ด ์ผ์ ๋ฐ์ด ๋ค์๋ค. ์ฌ๋ฐ๋ฅธ ๋ฐฉํฅ์ผ๋ก ๊ฐ๊ณ ์๋์ง ํ์ธํ๊ณ ์ถ์ต๋๋ค.
type parameters are not allowed on this type
์ค๋ฅ๋ฅผ ์์ ํ๊ธฐ ์ํด librustc_typeck/astconv.rs
qpath_to_ty
๋ฐ associated_path_def_to_ty
์ ๋ํ ์ ํ ๋งค๊ฐ๋ณ์ ๊ธ์ง๋ฅผ ์ญ์ ํ์ต๋๋ค. ๋ช ๊ฐ์ง ์ ๊ฒ์ผ๋ก ๊ต์ฒดํด์ผ ํ๋ค๊ณ ์๊ฐํฉ๋๋ค. ๋ํ...typeck ์คํจ๋ ์ฐ๊ด๋ ์ ํ์ด ์๋ ๊ฐ์ ์ ๋ค๋ฆญ์ ์ ๊ณตํ๊ธฐ ๋๋ฌธ์ src/test/compile-fail/struct-path-associated-type.rs
ํธ๋ฆฌ๊ฑฐ๋ฉ๋๋ค.
๋ด๊ฐ ์ฌ๋ฐ๋ฅด๊ฒ ์ฝ๊ณ ์๋ค๋ฉด ์ ์ด๋ ์ฐ๊ฒฐ๋ ์ผ๋ฐ ์นด์ดํธ๊ฐ ์ผ์นํ๋์ง ํ์ธํ๋ ๊ฒ์ฌ๋ฅผ ์ถ๊ฐํด์ผ ํ๊ณ (์ด๋์์ ์ํํ ์ง ์์๋ด๋ ค๊ณ ์๋ ์ค...) ๋ ธ๋ ๋ฑ์ ๋ํ ์ ํ์ ์ถ๊ฐํ๊ธฐ ์ํด ๋ค๋ฅธ ๊ฒ์ฌ๋ฅผ ์ํํ ์๋ ์์ต๋๋ค.
๊ทธ๊ฒ์ ๋ํด ์์ ํ ์์ ์ด์ง๋ง ์ฌ๋ฐ๋ฅธ ๋ฐฉํฅ์ผ๋ก ๊ฐ๊ณ ์๋์ง ์ฌ๋ถ์ ๋ํ ํฌ์ธํฐ๋ฅผ ์ฃผ์๋ฉด ๊ฐ์ฌํ๊ฒ ์ต๋๋ค.
์๋ ํ์ธ์ @brandonson๋! ๋๋ ๋๊ตฐ๊ฐ๊ฐ Rust ์ปดํ์ผ๋ฌ๋ฅผ ํดํนํ๋ ๊ฒ์ ๋ง๋ ๊ฒ์ ์ซ์ดํ์ง๋ง @sunjay ๋ ์ด๋ฏธ ๊ฐ์ ๊ฒ์ ํดํนํ๊ณ ์์๊ณ ์ฒ์๋ถํฐ ์ด ๋ณ๊ฒฝ์ ์ถ๊ตฌํด ์์ผ๋ฉฐ, ๋ฐ๋ผ์ ๊ทธ๋ค์ด ๋๋ด๋ ๊ฒ์ด ํฉ๋ฆฌ์ ์ผ ๊ฒ์ ๋๋ค. ์ด ๋ณ๊ฒฝ ์ฌํญ๋ ๋ง์ฐฌ๊ฐ์ง์ ๋๋ค(์ด๋ฏธ ์์๋ ๊ฒ ๊ฐ์ต๋๋ค). ์ด ๋ ธ๋ ฅ์ ๋ณ๋ ฌํํ๋ ํ์คํ ๋ฐฉ๋ฒ์ด ์๋์ง ํ์คํ์ง ์์ต๋๋ค(ํ์คํ ๊ฐ๋ฅํ์ง๋ง ๋ฏธ๋ฆฌ ๋จ๊ณ๋ฅผ ์ฝ๊ฐ ์กฐ์ ํด์ผ ํฉ๋๋ค).
๊ทธ๋ฌ๋ ํด๊ฒฐํด์ผ ํ ๋ฌธ์ ๋ฅผ ์ฐพ๋ ๋ฐ ๊ด์ฌ์ด ์๋ค๋ฉด ์ด ์ด์ ํ์์ ๋ช ๊ฐ์ง ๋ฒ๊ทธ๋ฅผ ํด๊ฒฐํ๋ ๊ฒ์ด ์ข์ต๋๋ค. https://github.com/rust-lang/rust/issues/46472 ์ ๋ํด ์ด์ผ๊ธฐํ์ง ์๋ ๊ฒ ๊ฐ์ต๋๋ค. ๊ณง ์๊ฒฌ์ ๋จ๊ธธ ์ ์์ต๋๋ค.
ํ์คํ ๋๋ ๋๊ตฐ๊ฐ์ ๋ฐ์ ๋ฐ์ ์๋๋ ์์ง๋ง ๋ ๋ง์ ์ง์ ์ด ์ค์ ๋ก ์ผ์ด๋๊ณ ์๋ค๋ ๊ฒ์ ๋ํ๋ด๋ ์ด๋ค ๊ฒ๋ ๋ณด์ง ๋ชปํ์ต๋๋ค(๋ฌผ๋ก ๋ค์ ๋จ๊ณ์ ๋ํ ์ธ๊ธ์ ๋ค์ ์ต๊ทผ์ด์ง๋ง). ์ฌ์ค, ์ง๋ ๋ฉฐ์น ๋์ GAT๋ฅผ ์ฌ๋ฌ ๋ฒ ์ํ๊ธฐ ๋๋ฌธ์ ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์์ํ์ต๋๋ค. ๋ฐ๋ผ์ ์์ผ๋ก ์ผ๋ถ NLL ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๋ฐ ์ ๊ฒฝ์ ์ฐ์ง ์์๋ ๋์ง๋ง ํด๊ฒฐํด์ผ ํ ํญ๋ชฉ ๋ชฉ๋ก์์ ์ด๊ฒ์ ํจ์ฌ ๋ ๋์ต๋๋ค. ์๊ฐ.
@sunjay , ์์ง ํ๋ฐํ ์์ ์ค์ด๊ฑฐ๋ ์์ ํ ๊ณํ์ด ์๋ค๋ฉด ์๋ ค์ฃผ์ญ์์ค. ์ด ์์ ์ ๋ณต์ ํ๋ ๊ฒ์ ์๋ฏธ๊ฐ ์์ต๋๋ค.
@brandonson ๋ ์๋ ํ์ธ์. ๊ธฐ๊บผ์ด ๋์์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค. :) ๋๋ ์ค์ ๋ก ์ด๊ฒ์ ๋ํด ์ ๊ทน์ ์ผ๋ก ๋ ธ๋ ฅํ๊ณ ์์ต๋๋ค. ์ ๋ Niko์ ๊ธด๋ฐํ ํ๋ ฅํ์ฌ ์ฌ๋ฐ๋ฅด๊ฒ ๊ตฌํํ๋ ๋์ ๊ตฌํ์ ๊ฐ ๋ถ๋ถ์ ๋จ๊ณ๋ณ๋ก ์ดํด๋ณด์์ต๋๋ค.
๊ฐ๋ฅํ ํ ๋นจ๋ฆฌ ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์๋๋ก ์ต์ ์ ๋คํ๊ฒ ์ต๋๋ค. ์ ๋ ์ด ๊ธฐ๋ฅ ์ ๋ง ๊ฐ๊ณ ์ถ์ด์!
์งํ ์ํฉ์ ์ด๋ป์ต๋๊น? =) ์ผ๊ฐ <3์์ ์ด๊ฒ์ ์คํํ๊ธฐ๋ฅผ ๊ธฐ๋ค๋ฆด ์ ์์ต๋๋ค.
GAT์ const ์ ๋ค๋ฆญ์ ํก๋จ๋ฉด์ด ์ด๋ป๊ฒ ์๋ํ๋์ง, ๊ทธ๋ฆฌ๊ณ ํจ๊ป ๊ฒฐํฉํ์ ๋ ์ ์์์ ์ผ๋ถ์๋์ง ๊ถ๊ธํฉ๋๋ค.
๋ด๊ฐ ์๋ฏธํ๋ ๋ฐ์ ์:
trait Foo {
type Bar<const N>;
}
์๋ ํ์ธ์ @sunjay ์ ๋ ์ด๊ฒ์ด ์๋นํ ์ค์ํ ๊ธฐ๋ฅ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค. 2018 ๋ก๋๋งต ๋๊ธ์์ ๋ง์ด ์ธ๊ธ๋์์ต๋๋ค. ์ด๋ป๊ฒ ์งํ๋๊ณ ์์ต๋๊น? ์์ ํด์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค!
ํ์ฌ ๊ฐ์ฅ ์ํ๋ ๊ธฐ๋ฅ์ ๋๋ค. ์ด๊ฒ์ด ์ฐ์ ์์๊ฐ ๋์ด ๊ณง ๋ฐค๋ฎ์ผ๋ก ์งํ๋๊ธฐ๋ฅผ ๋ฐ๋๋๋ค!
๊ทธ๋์ ์ต๊ทผ์ ํ๊ต์ ๋ค๋ฅธ ์ผ๋ก ์ง๊ธ ๋ฐ์ @sunjay ๋ฅผ ๋ง๋ ์ฌ๊ธฐ์์ ๋ค์ ๋จ๊ณ๋ฅผ ๊ณํํ๋ ค๊ณ ํฉ๋๋ค. ๊ทธ๋ค๊ณผ ๋๋ ์ด๋ ์์ ์์ ๋ง๋ ์ ๋ฐ์ ์ธ ๊ตฌํ ์ ๋ต์ ๋ํด ๋ ผ์ํ๊ณ , ๊ทธ๋ค์ ์ ์ฅ์์ ๋ํ ์ปค๋ฐ์์ ์ฐ๋ฆฌ๊ฐ ๋ง์ ์ธ๋ผ์ธ ์ฃผ์์ ๋จ๊ฒผ์ต๋๋ค .
์์ผ๋ก ๊ฐ์ฅ ์๋ฏธ ์๋ ์ ๋ต์ ๋ ๊ฐ์ง์ ๋๋ค.
๋ช ๊ฐ์ง ์ง์นจ re: ํ ์คํธ๋ฅผ ์์ฑํ๋ ๊ฒ์ผ๋ก ์์ํ๊ฒ ์ต๋๋ค. ํ ์คํธ๊ฐ ๋ ์ฆ๊ฐ์ ์ผ๋ก ์คํ ๊ฐ๋ฅํ๊ธฐ ๋๋ฌธ์ ๋๋ค. ๊ทธ๋ฆฌ๊ณ ์ด๋ฒ ์ฃผ ํ๋ฐ์ ๋๋จธ์ง ๋์์ธ์ด ์๋ํ๋ ๋ฐฉ์๊ณผ ์ฝ๋๋ฅผ ์๋ ์์น์์ ๊ฐ์ ธ์ค๋ ๋ฐฉ๋ฒ์ ์์ฑํ๊ธฐ ์ํด ์ผ์ ์ ์ก์ต๋๋ค. ์ด์ ํ์ํ ๊ณณ์ผ๋ก.
ํ๋ฅญ ํ๊ตฐ์ !! @sunjay ์ ์ด๋ฒ ์ผ๊ณผ ๋ค๋ฅธ ๋ชจ๋ ๋ ธ๋ ฅ์ ํ์ด์ ๋น๋๋ค.
์ฒซ ๋ฒ์งธ ๋จ๊ณ๋ ์ ์ฒด ํ ์คํธ ๋ชจ์์ด ์๋์ง ํ์ธํ๋ ๊ฒ์ ๋๋ค. ๊ธฐ์กด ํ ์คํธ๋ ๋ค์์์ ์ฐพ์ ์ ์์ต๋๋ค.
src/test/ui/rfc1598-generic-associated-types
๊ทธ๊ฒ๋ค์ ๋ณด๋ฉด ์ด๋ฏธ ์ํํด์ผ ํ ๋ช ๊ฐ์ง ์์ ์ ๋ณผ ์ ์์ต๋๋ค.
construct_with_other_type.rs
-- ์๊ธฐ์น ์์ E0110 ์ค๋ฅ ๋ฐ์empty_generics
-- type Bar<,>
์์ ์ค๋ฅ๊ฐ ๋ฐ์ํ๋์ง ํ์ธํ๊ณ ๊ด์ฐฎ์ ๊ฒ ๊ฐ์ต๋๋ค.generic-associated-types-where.rs
-- ์ฌ๋ฐ๋ฅธ ์์น์์ where
์ ์ ๊ตฌ๋ฌธ ๋ถ์ํ ์ ์๋์ง ํ์ธํฉ๋๋ค. ๊ด์ฐฎ์ ๊ฒ ๊ฐ์ต๋๋ค.generic_associated_type_undeclared_lifetimes.rs
-- ์๊ธฐ์น ์์ E0110 ์ค๋ฅ ๋ฐ์iterable.rs
-- ์๊ธฐ์น ์์ E0110 ์ค๋ฅ ๋ฐ์pointer_family.rs
-- ์๊ธฐ์น ์์ E0109 ์ค๋ฅ ๋ฐ์streaming_iterator.rs
-- ์๊ธฐ์น ์์ E0110 ์ค๋ฅ ๋ฐ์pointer_family
๋ ๊ทธ ๋ฐฉํฅ์ผ๋ก ๋ณด์
๋๋ค.trait Iterable { type Item; type Iter<'a>: Iterator<Item = &'a Self::Item>; }
ํ
์คํธ๋ฅผ ๊ธฐ๋ํฉ๋๋ค.trait Foo<'a> { type Item<'a>; }
impl<'a> Foo<'a> for &'a u32 { type Item<'a> = i32; }
pointer_family
ํ
์คํธ์๋ Self::Pointer<T>
๊ฐ ์์ง๋ง <Self as PointerFamily>::Pointer<T>
๋ ์์ต๋๋ค.Iterable
์ ์:<T as Iterable>::Item
-- ๋งค๊ฐ๋ณ์๊ฐ ์ ํ ์์ต๋๊น? ๋์.'_
๋ฅผ ์์ฑํ๋ ๊ฒ์ ์ ํธํฉ๋๋ค.<T as Iterable>::Item<'_>
-- ๋ง์ต๋๋ค!<T as Iterable>::Item<T>
-- ์ ํ์ด ๋๋ฌด ๋ง์ต๋๋ค!trait Foo { type Bar<T, U = T> where T: PartialEq<U>; }
SomeType::Bar<u32>
๋ SomeType::Bar<u32,u32>
์ ๋ํด ์งง์ ๊ฒ์ด๋ฏ๋ก ํ์ธํด์ผ ํฉ๋๋ค.prohibit_type_params
์์ ์ค๋ฅ E0110์ด ๋ณด๊ณ ๋์์ต๋๋ค.
์ฒซ ๋ฒ์งธ ๋จ๊ณ๋ ํธ์ถ๋ ์์น๋ฅผ ํ์
ํ๋ ๊ฒ์
๋๋ค. ๋ด๊ฐ ์ ํธํ๋ ๋ฐฉ๋ฒ์ ๋ก์ปฌ ๋น๋๋ฅผ ์ป๊ณ RUST_BACKTRACE=1
-Ztreat-err-as-bug
๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์
๋๋ค. ๊ทธ๋ฌ๋ Rustc๊ฐ ์์ง ๊ตฌ์ถ ์ค์ด๊ธฐ ๋๋ฌธ์ ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ๋ณด์ฌ๋๋ฆด ์ ์์ต๋๋ค. :P ๊ทธ๋์ ๋์ rg prohibit_type_params
์ ๋น ๋ฅด๊ฒ ์ํํ์ต๋๋ค. ์ ๊ฐ ๋ณธ ์์ํ ์ฌ๋ก ํ๋๋ฅผ ๋น ๋ฅด๊ฒ ์ง์ ํ๊ฒ ์ต๋๋ค.
ํ๋์ ํธ์ถ์ associated_path_def_to_ty
์
๋๋ค.
์ฃผ์์์ ์ ์ ์๋ฏ์ด Self::Pointer<T>
์ ๊ฐ์ ๊ฒฝ๋ก์์ Pointer<T>
๊ตฌ์ฑ ์์๋ฅผ ํ์ธํ๊ธฐ ์ํด ํธ์ถ๋ฉ๋๋ค(์ ํ ๋งค๊ฐ๋ณ์๋ ์ฒจ๋ถ๋ ์ด๋ฆ๊ณผ ํจ๊ป ๊ฒฝ๋ก ์ธ๊ทธ๋จผํธ์ ์ผ๋ถ๋ก ๊ฐ์ฃผ๋ฉ๋๋ค. ). GAT ์ด์ ๊น์ง๋ ์ ํ ๋งค๊ฐ๋ณ์๊ฐ ์ ํจํ์ง ์์์ผ๋ฏ๋ก(์: T::Item
) ํฌ๊ด์ ์ธ ์ ํ์ด ์์ต๋๋ค.
๋ถ๋ช
ํ ์ด๊ฒ์ ํ์ง ์์ ๊ฒ์
๋๋ค. ํด๋น ํ์ ์ ๊ฑฐํ๊ณ ๋งค๊ฐ๋ณ์๊ฐ ์ ๊ณต๋๋ฉด ์์ ์ซ์์ ์ผ์นํ๋์ง ํ์ธํ๋ ์ผ์ข
์ ๊ฒ์ฌ๋ก ๋์ฒดํด์ผ ํฉ๋๋ค. ์ด๋ฅผ ์ํด create_substs_for_ast_path
์ ์๋ ๊ฒ๊ณผ ์ ์ฌํ ์ค๋ฅ ๊ฒ์ฌ ์ฝ๋๊ฐ ํ์ํ ๊ฒ์
๋๋ค. ํนํ ๊ธฐ๋ณธ๊ฐ์ด ์๋ ๊ณ์ ์ ์ํด ์ฌ๊ธฐ์ ๊ณต์ ์ฝ๋๋ฅผ ๋ง๋ค๊ณ ์ถ์ ๊ฒ์
๋๋ค. ์ค์ ๋ก ํด๋น ๊ธฐ๋ฅ์ ์ฌ์ฌ์ฉํ ์ ์์๊น์?
์์ง ์์ ์ค์ธ ์ฌ๋์ด ์์ต๋๊น? ์ด๊ฒ ๊ฐ ๊ธธ์ด ๋จผ ๊ฒ ๊ฐ์ต๋๋ค. GAT๋ ๋ด๊ฐ ๊ฐ์ฅ ์ํ๋ RFC์ ๋๋ค. ๊ทธ๋ ์ง ์๋ค๋ฉด ๋ช ๊ฐ์ง ํ ์คํธ์ ๊ธฐ์ฌํ๊ณ ์ถ์ต๋๋ค ...
@rickyhan ๊ทธ๋์ @Centril ๊ณผ @gavento ๋ ํ ์คํธ ์์ ์ ๋ถํ ํ๋ ๊ฒ์ ๋ํด WG ํน์ฑ ์ ๋ํด ์ด์ผ๊ธฐํ๊ณ ์์์ง๋ง ์ง์ ์ด ์์๋์ง ๋ชจ๋ฅด๊ฒ ์ต๋๋ค. ์๋ง๋ ๊ทธ๋ค์ด ์ฐจ์๋ฒจ์ ์ธ๋ฆด ์ ์์ ๊ฒ์ ๋๋ค. ์ ์๊ฐ์ PR์ ํ์๋ฐ์ ๊ฒ์ ๋๋ค. =)
๋ด๊ฐ ๋ฐ๋ณด๋ผ๋ฉด ๋ฏธ์ํ์ง๋ง GAT์์ ์ด๋ฐ ์ข ๋ฅ์ ๊ฒ์ด ํฉ๋ฒ์ ๋๊น?
trait Sequencer {
type Wrap<A>;
fn chain<A, B, F>(Self::Wrap<A>, F) -> Self::Wrap<B>
where F: FnOnce(A) -> Self::Wrap<B>;
fn wrap<A>(A) -> Self::Wrap<A>;
}
์ด ์ํ๋ ์ด๋ป์ต๋๊น? ๋๋ ๊ทธ ๋ถํ์ด ์ต๊ทผ์ ๊ฐํธ ์ง์ง๋ฅผ ์ป์๋ค๋ ๊ฒ์ ์๊ณ ์์ต๋๋ค. ๊ณง ๋ น์ด ์ฌ๊ธฐ ์ํ ๊ฒ์ ๋๊น?
@mark-im ์ง๋์ฃผ์ ํ๋ฒ ํด๋ดค์ต๋๋ค. ๋ด ์ดํด์ ๋ฐ๋ฅด๋ฉด ๊ตฌ๋ฌธ ํ์๊ฐ ์์ต๋๋ค(ํ ์คํธ๊ฐ ๋๋ฝ๋์์ง๋ง). ๊ทธ๋ฌ๋ "๊ตฌํ"์ ์์ง ์์ฑ๋์ง ์์์ต๋๋ค. (์์ธํ ๋ด์ฉ์ https://github.com/rust-lang/rust/issues/44265#issuecomment-330915766 ์ฐธ์กฐ)
@quadrupleslap AIUI, ๋์ค์ ๊ฐ๋ฅํ๊ฒ ์ง๋ง ์ฒ์์๋ GAT๊ฐ ํ์ ๋งค๊ฐ๋ณ์๋ง ์ง์ํฉ๋๋ค..
@Boscop RFC๋ ์ ํ ๋งค๊ฐ๋ณ์๋ ์ง์ํ๋๋ก ์ง์ ํฉ๋๋ค.
๋๊ตฐ๊ฐ Rustc์์ ๊ตฌ๋ฌธ ๊ตฌํ์ ์ ํํ ์ํ๋ฅผ ์๊ณ ์์ต๋๊น? ๋๋ถ๋ถ ์๋ ๊ฒ ๊ฐ์ง๋ง ์์๊ฐ ๋์์๋ก ICE๊ฐ ์์ฑ๋ฉ๋๋ค.
http://play.rust-lang.org/?gist=a48959858ed5dd432c2396feae5c3cc1&version=nightly&mode=debug
๋๋ ๋ถํ ์์ ์ ์งํํ๊ธฐ ์ํด ์ต์ํ ์ ์ฒด ๊ตฌ๋ฌธ์ ๊ตฌํํด์ผ ํฉ๋๋ค. ์์ง ๊ตฌ๋ฌธ ์์ ์ ํ๊ณ ์๋ ์ฌ๋์ด ์๋ค๋ฉด ์๋ ค์ฃผ์ธ์. ๊ทธ๋ ์ง ์์ผ๋ฉด ์ ๊ฐ ์ง์ ๊ณ ์น ์๋ ์์ต๋๋ค. :)
๋ด๊ฐ ๋ณด๊ธฐ์๋ ์ปค๋ฎค๋์ผ์ด์ ์ด GAT ๊ตฌํ ์๋๋ฅผ ๋ฆ์ถ๋ ์ฃผ์ ๋ฌธ์ ์ธ ๊ฒ ๊ฐ์ต๋๋ค. ์ด ์์ ์ ๊ด์ฌ์ด ์๋ ์ฌ๋์ด ์ต์ํ ๋ช ๋ช ์๋ ๊ฒ ๊ฐ์ง๋ง ์ ํํ ๊ตฌํ ์ํ์ ์ด๋ฏธ ์์ ์ค์ธ ์ฌ๋์ ์๋ฌด๋ ์์ต๋๋ค. GAT ๊ตฌํ์ ๋ํด ์ด์ผ๊ธฐํ๊ธฐ ์ํด Discord(๋๋ IRC?) ์ฑ๋์ ๋ํด ์ด๋ป๊ฒ ์๊ฐํ์ญ๋๊น? ๋๋ ๊ทธ๊ฒ์ด ํ์คํ ๋์์ด ๋ ๊ฒ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค.
๋ํ ๋ค์ ์ฃผ์ ๋ช ์ผ ๋์ ์ด ์์ ์ ์ํํ ์ ์์ต๋๋ค.
๊ทธ๋์ Discord์ ์ ์ฉ ์ฑ๋์ ์์ฒญํ์ต๋๋ค. ํ์ง๋ง ์ฑ๋์ ์ป๋ ๋์ ๋ช ๊ฐ์ง๋ฅผ ๋ฐฐ์ ์ต๋๋ค. ๋ํ GAT์ ๊ด๋ จ๋ ๋ชจ๋ ๊ฒ์ ๊ฒ์ํ์ต๋๋ค. ๋ฐ๋ผ์ ์ด ๊ธฐ๋ฅ์ ๋ํ ๋ชจ๋ ์ ๋ณด๋ฅผ ์์ฝํ๋ ค๊ณ ํฉ๋๋ค. ์๋ง๋ ์ด๋ค ์ฌ๋๋ค์๊ฒ๋ ์ ์ฉํ ๊ฒ์ ๋๋ค. ๊ทธ๋ฌ๋ ๋๋ ์๋ฌด๊ฒ๋ ๋ชจ๋ฅด๋ฏ๋ก ์ด๊ฒ์ ์๊ธ ํ ์๊ณผ ํจ๊ป ๊ฐ์ ธ ๊ฐ๋ผ! ๋ํ: ์ผ๋ถ ์ ๋ณด๊ฐ ์๋ชป๋ ๊ฒฝ์ฐ ์๋ ค์ฃผ์๋ฉด ์์ ํ ์ ์์ต๋๋ค.
@sunjay ๋ ๋ ๊ฐ์ ๋ฉ์ง PR์ ๋ฐ์์ต๋๋ค.
๊ทธ๋ฐ ๋ค์ ํ๋์ ๋ง์ ์ผ์ด ์ผ์ด๋์ง ์์์ต๋๋ค. ๊ทธ๋ฐ ๋ค์ Niko ๋ ์ด ์๊ฒฌ(2018-03-12)์์ ์ฌ์ ํ ๋ฐ์ํด์ผ ํ๋ ์ผ์ ์์ฝํ์ต๋๋ค. ๊ธฐ๋ณธ์ ์ผ๋ก (a) ํ ์คํธ ์์ฑ, (b) ํ์/ํ๋ก ํธ ์๋์ ๋ฒ๊ทธ ์์ /๊ฐ์ ๋ฐ (c) ํน์ฑ ์์คํ ์ ๊ตฌํ. ์ (a)๋ ์ด ์๊ฒฌ (2018-03-13)์์ ์ถ๊ฐ๋ก ์ค๋ช ๋์์ต๋๋ค.
@gavento ๋ RFC1598(GAT)์ ๋ํ ํ์ฅ ํ ์คํธ๋ฅผ ์์ํ์ต๋๋ค( 2018-05-11 ๋ณํฉ).
๊ทธ ์ดํ๋ก UI ํ ์คํธ๊ฐ ์ถ๊ฐ๋์ง ์์์ต๋๋ค . ๊ทธ๋ฆฌ๊ณ GAT์ ์ง์ ์ ์ผ๋ก ๊ด๋ จ๋ ๋ค๋ฅธ PR์ ์ฐพ์ ์ ์์ต๋๋ค.
๊ทธ๋ฌ๋ ์์ (c)(ํน์ฑ ์์คํ )์ "๋น๋ฐ๋ก" ์์ ์ค์ ๋๋ค. ๋ด๊ฐ ์ดํดํ๋ ํ, ๊ณํ์ ๊ณง ์๋ก์ด ๋ถํ ๊ธฐ๋ฐ ํน์ฑ ์๋ฒ๋ก ๋ง์ด๊ทธ๋ ์ด์ ํ๊ณ GAT๊ฐ ์ด์ ์์คํ ์์ ์๋ ํ์ง ์๋๋ก ํ๋ ๊ฒ์ ๋๋ค. ์๋ก์ด ํน์ฑ ์๋ฒ์ ํตํฉ์ "Chalkification" ์ถ์ ๋ฌธ์ ๋ก ์ถ์ ๋ฉ๋๋ค. ๋ถํ ๋ฐ ๋ฐฑ์ ํ์ ๊ด๋ จ๋ ๊ฝค ๋ง์ PR์ด ์์์ต๋๋ค. ํนํ "GAT ๊ตฌํ ์๋ฃ" (2018-05-24 ๋ณํฉ)๋ผ๋ ์ดํฌ PR์ด ์์ต๋๋ค. ๋ฐ๋ผ์ GAT์ ํต์ฌ ์์คํ ์ ์ด๋ฏธ ์ ์๋ฆฌ์ ์๋ ๊ฒ ๊ฐ์ต๋๋ค.
์ฆ, ๋ถํ๋ก ํ์๋ "GAT"๋ ํ๋กํ ํ์
๊ตฌํ์ด๋ฉฐ rustc์์ ์ฌ์ฉํ๋ ๊ฒ์ ๋จ์ง use chalk;
๊ฐ ์๋๋๋ค. @scalexm ์ด ๋์๊ฒ ๋งํ๋ฏ์ด: "ํ ์ผ์ด ๊ฝค ๋ง์ ๊ฒ ๊ฐ์ต๋๋ค."
๋ ๋ง์ ์ ๋ณด๋ฅผ ์ป๊ณ ๋์์ ๋ฐ์ผ๋ ค๋ฉด #wg-traits
Discord ์ฑ๋๊ณผ WG ์ถ์ ๋ฌธ์ ํน์ฑ ์ ์ดํด๋ณด๋ ๊ฒ์ด ๋์์ด ๋ ๊ฒ์
๋๋ค.
๊ทธ๋์ @nikomatsakis ๋ rust-lang discord ์๋ฒ์ #wg-traits-gat
์ฑ๋์ ๋ง๋ค์์ต๋๋ค( ์ฌ๊ธฐ์ ๊ฐ์
ํ์ธ์ ). ์ฐ๋ฆฌ๊ฐ ๊ฑฐ๊ธฐ์์ ๋์์ ์ํ๋ ๋ชจ๋ ์ฌ๋์ ์ป์ ์ ์๋ค๋ฉด ์ข์ ๊ฒ์
๋๋ค. ๋ํ ์ด ๊ธฐ๋ฅ์ ์ํ(ํนํ ์์ง ์ํํด์ผ ํ ์์
๊ณผ ๋์์ด ํ์ํ ๋ถ๋ถ)์ ๋ํด ์๊ณ ์๋ ์์์ ์ฌ๋๋ค์ด ์์ต๋๋ค. ์ด๋ ํนํ ์ ์ ๊ฐ์ด ์์ง ๊น์ด ๊ด์ฌํ์ง ์์/WG ํน์ฑ์ ์ผ๋ถ์ธ ์ฌ๋๋ค์ ์ํด ๋ ์ฝ๊ณ ๋น ๋ฅด๊ฒ ์์ฌ ์ํต์ ํ ์ ์๋๋ก ํด์ผ ํฉ๋๋ค. :)
์ต๊ทผ์ ์ด์ ๋ํ ์ ๋ฐ์ดํธ๊ฐ ์์ต๋๊น? Chalk๊ฐ ์ปดํ์ผ๋ฌ์ ํตํฉ๋๊ธฐ๋ฅผ ๊ธฐ๋ค๋ฆฌ๊ณ ์์ต๋๊น? (์๋ง๋ ๊ทธ๊ฒ์ ๋ํ ๋ณ๋์ ๋ฌธ์ ๊ฐ์์ ๊ฒ์ ๋๋ค.)
์๋ง๋ ๊ทธ๊ฒ์ ๋ํ ๋ณ๋์ ๋ฌธ์ ๊ฐ ์์ ๊ฒ์ ๋๋ค.
์ฐธ๊ณ ๋ก(์๋ ค์ ธ ์์ ์๋ ์์) ์ด ์ฝ๋๋ ์ปดํ์ผ๋ฌ๋ฅผ ํจ๋ ์ํ๋ก ๋ง๋ญ๋๋ค.
use typenum::{U1,U2,U3,Unsigned};
trait Array {
type Of<Elem> ;
}
impl Array for U1 { type Of<T> = [T;1]; }
impl Array for U2 { type Of<T> = [T;2]; }
impl Array for U3 { type Of<T> = [T;3]; }
@varkor ๊ต์ฅํฉ๋๋ค, ๊ฐ์ฌํฉ๋๋ค!
๋ ๋ค๋ฅธ ๋ฉ๋ชจ(๋ค์, ์๋ง๋ ์๋ ค์ง). GAT๊ฐ ์์ผ๋ฉด &
๋ฐ &mut
์ ํ์ ๋ํด ๋ฉ์ง๊ฒ ์ถ์ํํ ์ ์์ผ๋ฏ๋ก my_func
๋ฐ my_func_mut
ํจ์ ๊ฐ์ ์ฝ๋๋ฅผ ์ง์์ ์ผ๋ก ๋ณต์ฌํ์ฌ ๋ถ์ฌ๋ฃ๋ ๊ฒ์ ์ค์งํ ์ ์์ต๋๋ค.
#![feature(arbitrary_self_types)]
#![feature(generic_associated_types)]
use std::marker::PhantomData;
struct Pure <'t> (PhantomData<&'t()>);
struct Mut <'t> (PhantomData<&'t()>);
type Ref<M, T> = <M as Acc>::Pat<T>;
trait Acc { type Pat<T: ?Sized>; }
impl<'t> Acc for Pure <'t> { type Pat<T> = PureRef <'t, T>; }
impl<'t> Acc for Mut <'t> { type Pat<T> = MutRef <'t, T>; }
struct PureRef <'t, T: ?Sized> (&'t T);
struct MutRef <'t, T: ?Sized> (&'t mut T);
/// USAGE ///
struct Buf<T> {
data: Vec<T>
}
impl<T> Buf<T> {
fn as_mut<M: Acc>(s: Ref<M, Self>) -> Ref<M, [f32]>
{
unimplemented!()
}
}
๊ฑฐ์ ์ปดํ์ผ๋ฉ๋๋ค. GAT ์์ด ๊ตฌํํ ์๋ ์์ง๋ง ์ ํ์ ํญ๋ฐ์ ์ ๋๋ค.
#![feature(arbitrary_self_types)]
use std::marker::PhantomData;
use std::ops::Deref;
struct Pure <'t> (PhantomData<&'t()>);
struct Mut <'t> (PhantomData<&'t()>);
type Ref<M, T> = <M as Acc<T>>::Pat;
trait Acc<T: ?Sized> { type Pat; }
impl<'t, T: 't + ?Sized> Acc<T> for Pure <'t> { type Pat = PureRef <'t, T>; }
impl<'t, T: 't + ?Sized> Acc<T> for Mut <'t> { type Pat = MutRef <'t, T>; }
struct PureRef <'t, T: ?Sized> (&'t T);
struct MutRef <'t, T: ?Sized> (&'t mut T);
/// USAGE ///
struct Buf<T> {
data: Vec<T>
}
impl<T> Buf<T> {
fn as_mut<M>(self: Ref<M, Self>) -> Ref<M, [f32]>
where M: Acc<Self> + Acc<[f32]>,
Ref<M, Self>: Deref<Target = Self>
{
unimplemented!()
}
}
(์ด๊ฒ์ ์ค์ ๋ก ์ปดํ์ผ๋จ)
์๋ง๋ ์ด๊ฒ์ ์ง์ ์ง๋ฌธ์ ๊ฐ๊น์ง๋ง RFC ๋๋ ์ฌ๊ธฐ์ ์๊ฒฌ์์ ์์ ํ ๋ช ํํ์ง ์์๊ธฐ ๋๋ฌธ์ ์ด ํ์ด์ง์ ์ค๋ ์ฌ๋๋ค์ด ์ด ์ ์์ ์ดํดํ๋ ๊ฒ์ด ์ ์ฉํ ์ ์๋ค๊ณ ์๊ฐํฉ๋๋ค.
1.41 nightly๋ฅผ ์ฌ์ฉํ์ฌ ๋ค์์ ์๋ํ์ต๋๋ค.
pub trait MyTrait {
type MyType<U>;
fn f<U>(self, x : <Self as MyTrait>::MyType<U>);
}
๊ทธ๋ฆฌ๊ณ ์ด๊ฒ์ "์ ํ ์ธ์๊ฐ ํ์ฉ๋์ง ์์" MyType
์ค๋ฅ๊ฐ ๋ฐ์ํ์ฌ ์ปดํ์ผ์ ์คํจํฉ๋๋ค.
๊ทธ๋ฐ ๋ค์ ์์ฌ์ค๋ฌ์ ๋ณด์ด๋ <U>
๋ฅผ ์ ๊ฑฐํ์ง๋ง ์๋ํด ๋ณด๊ฒ ์ต๋๋ค.
pub trait MyTrait {
type MyType<U>;
fn f<U>(self, x : <Self as MyTrait>::MyType);
}
๋๋๊ฒ๋ ์ปดํ์ผ๋์์ต๋๋ค. ๊ทธ๋ฌ๋ ๋ด๊ฐ impl์ ์์ฑํ ๋ :
impl MyTrait for u64 {
type MyType<U> = U;
fn f<U>(self, x : <Self as MyTrait>::MyType) -> <Self as MyTrait>::MyType {
x;
}
}
์ด๊ฒ์ ์ปดํ์ผ๋ฌ๋ฅผ ํจ๋ ์ํ๋ก ๋ง๋ค์์ต๋๋ค.
๋ด ์ง๋ฌธ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
์๊ฐ์ ๋ด์ด ๋ต๋ณํด ์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค.
@clintonmead ๋๋ ๊ทธ๊ฒ์ด ๊ฒฐ๊ตญ ๊ฐ๋ฅํด์ผ ํ๋ค๊ณ ์๊ฐํ์ง๋ง ๊ธฐ๋ฅ ๊ตฌํ์ ์์ง ์๋ฃ๋์ง ์์์ต๋๋ค(์ฌ์ค, ์ปดํ์ผ๋ฌ๋ ์ฌ์ฉํ๋ ค๊ณ ํ ๋ ์ถฉ๋ํ ์ ์๋ค๊ณ ๊ฒฝ๊ณ ํฉ๋๋ค!). ํ์๋ผ์ธ์ด ๋ญ์ง ๋ชจ๋ฅด๊ฒ ๋ค์.
์ด ๊ธฐ๋ฅ์ ๋ํ ์์ ์ ์ฌ๊ฐํ ์ ์์ ๋งํผ ํตํฉ์ด ์ถฉ๋ถํ ์งํ๋์๋์ง ํ์ธํ๊ธฐ ์ํด Chalk ์ง์์๊ฒ ํ์ธํด ๋ณผ ๊ฐ์น๊ฐ ์์ต๋๊น?
์ด๊ฒ์ ์ด์ ์ฐจ๋จ๋์์ต๋๋ค.
ํ์ฌ ์ฐจ๋จ๊ธฐ๋ก ์ ๋ฐ์ดํธ๋ ๋ฌธ์ ์ค๋ช ์ ์ป์ ์ ์์ต๋๊น?
@DutchGhost ๊ฐ ์ ๊ธฐํ ๋ ๋ง์ ์ฐจ๋จ ๋ฌธ์ ์ถ๊ฐ
์ด๊ฒ์ ๋ ๋์ ์ข ๋ฅ์ ์ ํ์ ์๋ฎฌ๋ ์ด์ ํ๋ ์ฃผ์ ๋จ๊ณ๊ฐ ๋ ๊ฒ์ ๋๋ค.
๋๋ ๋ค์๊ณผ ๊ฐ์ ๊ฒ์ ์์ํ๊ณ ์์ต๋๋ค.
// the plug/unplug idea is from https://gist.github.com/edmundsmith/855fcf0cb35dd467c29a9350481f0ecf
trait Monad /* : Applicative (for pure/return, doesn't matter for this example) */ {
// Self is like the "f a" in haskell
/// extract the "a" from "f a"
type Unplug;
/// exchange the "a" in "f a" in the type of Self with B
type Plug<B>: Monad;
fn bind<B, F>(this: Self, f: F) -> Self::Plug<B>
where
F: Fn(Self::Unplug) -> Self::Plug<B>;
}
impl<A> Monad for Option<A> {
type Unplug = A;
type Plug<B> = Option<B>;
fn bind<B, F>(this: Self, f: F) -> Option<B>
where
F: Fn(A) -> Option<B> {
this.and_then(f)
}
}
์ ์๋ ๊ตฌํ์ ๋ํ ์ง๋ฌธ:
์ด๋ ๊ฒ ์๊ธด ํน์ง์ด ์์ด์
trait TradeableResource{
}
๊ทธ๋ฆฌ๊ณ ๋ค์๊ณผ ๊ฐ์ ๊ตฌํ์
struct Food(f64);
impl TradeableResource for Food{}
๋ด ํน์ฑ์ ๋ชจ๋ ๊ตฌํ์๋ฅผ "newtype"(f64๋ฅผ ๋ํํ๋ ๋จ์ผ ์์ ํํ ๊ตฌ์กฐ์ฒด)๋ก ์ ํํ ์ ์๊ธฐ๋ฅผ ๋ฐ๋๋๋ค.
์ ์๋ ๊ตฌํ์ด ์ฌ๊ธฐ์์ ๊ณ ๋ ค๋๋ค๋ฉด ๊ฐ๋ฅํ ๊น์?
๋ค์์ ์ฝ๊ฐ ์ด์ํ๊ฒ ๋ณด์ด์ง๋ง ๋ด๊ฐ ํ ์ ์๊ธฐ๋ฅผ ์ํ๋ ๊ฒ์ ๋ณด์ฌ์ฃผ๊ธฐ๋ฅผ ๋ฐ๋๋๋ค.
trait TradeableResource{
type Wrapper<T>:T(f64)
}
@ChechyLevas ๋ด๊ฐ ์๋ ํ ์ด๊ฒ์ GADT์ ๋ฒ์์ ์ํ์ง ์์ต๋๋ค.
๊ทธ๋ฌ๋ ๋น์ ์ดํ๊ณ ์ถ์ ๊ฒ์ GADT๊ฐ ํ์ํ์ง ์์ต๋๋ค. ๋ด๊ฐ ์์ง ํ ์์๋ ๊ฒ์์, ๋น์ ์ด ๊ทธ๊ฒ์ด ์๋ก์ด ์ ํ์ด๋ผ๋ ๋ณด์ฅ์ ๊ธฐ๊บผ์ด ํฌ๊ธฐํ๊ณ ๋์ ๋ด๋ถ ๊ฐ์ ๊ฐ๊ฐ ๊ฐ์ธ๊ณ ๊ฒ์ํ๋ ๊ธฐ๋ฅ์ ๊ฐ์ ธ์ผํ๋ค๋ฉด . ํธ๋ฆฌํ์ง๋ ์์ง๋ง ์ถฉ๋ถํ ์ ์๋ํด์ผ ํฉ๋๋ค.
๋ฐ๋ผ์ ๋ค์์ ์ํํ ์ ์์ต๋๋ค.
trait Traceable resource: From<f64> + Into<f64> { }
(์ด๊ฒ์ ๋งคํฌ๋ก๋ฅผ ํตํด ์ํํ ์๋ฐฉํฅ์ผ๋ก From
๋ ๊ตฌํํด์ผ ํฉ๋๋ค.)
์ด ์ํฉ์ ๋ํด ์ฝ๊ฐ์ ๋๋์ ๋ฐ๊ณ ์ถ์ต๋๋ค. ๋๋ ๋น๋๊ธฐ ํน์ฑ๊ณผ ์๋ช
์ ์ฝ๊ฐ ๊ฐ์ง๊ณ ๋์์ต๋๋ค.
๋ด๊ฐ ํ๊ณ ์ถ์๋ ํ ๊ฐ์ง๋ ReadAt: Future
trait ReadAt<'r>
๋ฅผ ๋ง๋๋ ๊ฒ์ด์์ต๋๋ค. ํน์ฑ ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ๋ ค๋ ๊ฒฝ์ฐ๋ฅผ ์ ์ธํ๊ณ ๋ ๋ง์ ๊ฒฝ์ฐ์ ์๋ํฉ๋๋ค.
์ฃผ๋ก ๋ค์์ ์ํํ๋ฉด ์ผ๋ฐ์ ์ด์ง ์์ ์๋ช
์ R
์ ์ฒจ๋ถํด์ผ ํ๊ธฐ ๋๋ฌธ์
๋๋ค.
impl<'a, 'r, R> ReadAt<'r> for &'a dyn for<'z> ReadAt<'z, ReadAt = R> + 'a {
type ReadAt = R; // cannot have an `impl<R<'lifetime>>`
...
}
๊ทธ๋์ ๋๋ ์ด๊ฒ์ด GAT๋ก ํด๊ฒฐ๋ ์ ์์์ง๋ ๋ชจ๋ฅธ๋ค๊ณ ์๊ฐํ์ง๋ง, ํน์ฑ ๊ฐ์ฒด๊ฐ ๊ด๋ จ ์ ํ์ ์์ฑํด์ผ ํ๊ธฐ ๋๋ฌธ์ ๊ตฌ๋ฌธ ๋ง๋ฒ์ด ๋ค์ ํ์ํ ์ ์ฌํ ๋ฌธ์ ์ ๋ถ๋ช์ณค์ต๋๋ค.
์ฒ๋ผ:
trait ReadAt {
type ReadAt<'r>: Future<Output = io::Result<usize>>;
fn read_at<'a>(&'a self, buf: &'a mut [u8], at: u64) -> Self::ReadAt<'a>;
}
impl<'d> ReadAt for &'d (dyn ReadAt<HERE> + 'd) {
}
HERE
์ ์๋ช
์ ํฌํจํ๋ ๋ฐฉ๋ฒ์ด ํ์ํฉ๋๋ค. ์๋ฅผ ๋ค์ด ์ด๊ฒ์ ํ์ฉ๋์ง๋ง R
๊ฐ ๋๋ฌด ๊ตฌ์ฒด์ ์ด๋ฏ๋ก IMO๊ฐ ์ถฉ๋ถํ์ง ์์ต๋๋ค.
impl<'d, R> ReadAt for &'d (dyn ReadAt<ReadAt = R> + 'd) {
type ReadAt<'r> = R;
fn read_at<'a>(&'a self, buf: &'a mut [u8], at: u64) -> Self::ReadAt<'a> {
(**self).read_at(buf, at)
}
}
ํ์ง๋ง ์ด๊ฒ์ด ์ด๋ป๊ฒ ์๋ํ๋์ง ํ ์คํธํ ์๋ ์์ต๋๋ค. ๋ค์ ์ค๋ํซ์ ์๋ช ์ ์ด๋ป๊ฒ ๊ฐ์ ธ์ฌ์ง ๋ชจ๋ฅด๊ธฐ ๋๋ฌธ์ ์ด๊ฒ์ ํน์ฑ ๊ฐ์ฒด๋ก ๋ฐ๊พธ๋ ๋ฐฉ๋ฒ์ ์ ๋ชจ๋ฅด๊ธฐ ๋๋ฌธ์ ๋๋ค.
struct Test<T: ReadAt>(T);
impl<T: ReadAt> Test<T> {
fn into_trait_object<'a>(&'a self) -> Test<&'a dyn ReadAt<ReadAt = T::ReadAt>> {
todo!();
}
}
T::ReadAt
๋ ๋ด๊ฐ ์ ๊ณตํ ์ ์๋ ์๋ช
์ด ๊ฑธ๋ฆฌ๋ฏ๋ก dyn ReadAt<ReadAt<'r> = T::ReadAt<'r>>
์ ๋ํ ๊ตฌ๋ฌธ ํ์ฅ์ ๋์น๊ฒ ๋ฉ๋๋ค. (๋๋ ์ผ์นํ๋ ์๋ช
๋งค๊ฐ๋ณ์์ ๊ฒฝ์ฐ IMO ์์ ์ค๋ํซ์ด ์๋ํ ์ ์์ต๋๋ค. ;-) )
์ ํ ๋งค๊ฐ๋ณ์๊ฐ ์๋ ์๋ช ๋งค๊ฐ๋ณ์๋ง ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ์๋ช ๋งค๊ฐ๋ณ์๊ฐ vtable๊ณผ ์ ํ ํฌ๊ธฐ์ ์ด๋ป๊ฒ๋ ์ํฅ์ ์ค ์ ์๋ค๋ฉด ๊ธฐ์ ์ ์ผ๋ก ๊ฐ๋ฅํด์ผ ํ๋ค๊ณ ์๊ฐํฉ๋๋ค.
@jendrikw ์ฝ๋๋ ์ต์ nightly(1.46)๋ก ์ปดํ์ผ ๋ฐ ์คํ๋ฉ๋๋ค. ์ฌ์ฉ์ ์ ์ ์ ํ ๋ฑ์ผ๋ก ๋ช ๊ฐ์ง ํ ์คํธ๋ฅผ ์ํํ์ง๋ง ๋ ๋ง์ ๊ฒ์ ํ์ธํ fp ์ง์์ด ๋ถ์กฑํฉ๋๋ค.
์ค๋, ๋๋ ์๋ง๋ ํ์์ด ์ถฉ๋ถํ ์ผ๋ฐ์ ์ด์ง ์์ ๊ฒ์ด๋ผ๊ณ ์๊ฐํ๋ ์ผ์ GAT๋ฅผ ์ฌ์ฉํด ๋ณด์์ต๋๋ค(์์ ์ฝ๋๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค. ์์ ํ ์ฝ๋ ํ์ผ ):
/// Helper trait for "stripping indention" from an object reference
pub trait AsUnindented<'ast> {
type Output;
/// Returns a reference to the unindented part of `Self`
fn as_unindented(&'ast self) -> Self::Output;
}
impl<'ast, T: 'ast> AsUnindented<'ast> for Indented<T> {
type Output = &'ast T;
#[inline]
fn as_unindented(&'ast self) -> &'ast T {
&self.data
}
}
impl<'ast, T: 'ast> AsUnindented<'ast> for crate::Block<T>
where
T: AsUnindented<'ast> + 'ast,
{
type Output = crate::View<'ast, T, fn(&'ast T) -> T::Output>;
#[inline]
fn as_unindented(&'ast self) -> Self::Output {
crate::View::new(self, T::as_unindented)
}
}
๊ทธ๋ฐ ๋ค์ ๋ค์ ์ฝ๋์์ GAT๋ฅผ ์ฌ์ฉํด ๋ณด์์ต๋๋ค.
pub trait AsUnindented {
type Output<'ast>;
/// Returns a reference to the unindented part of `Self`
fn as_unindented<'ast>(&'ast self) -> Self::Output<'ast>;
}
impl<T> AsUnindented for Indented<T> {
type Output<'ast> = &'ast T;
#[inline]
fn as_unindented<'ast>(&'ast self) -> &'ast T {
&self.data
}
}
impl<T> AsUnindented for crate::Block<T>
where
T: AsUnindented,
{
type Output<'ast> = crate::View<'ast, T, fn(&'ast T) -> T::Output<'ast>>;
#[inline]
fn as_unindented<'ast>(&'ast self) -> Self::Output<'ast> {
crate::View::new(self, T::as_unindented)
}
}
์๋ํ์ง ์์ต๋๋ค. ๋ ํน์ฑ ๊ตฌํ ๋ชจ๋ E0309
( the parameter type 'T' may not live long enough
)๋ก ์คํจํฉ๋๋ค. ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๋ฐฉ๋ฒ์ด๋ ์ ๊ฐ ์๋ชป ์๊ณ ์๋ ๊ฒ์ด ์๋์ง ์ ๋ชจ๋ฅด๊ฒ ์ต๋๋ค. ์ปดํ์ผ๋ฌ๋ impl
์์ค์์ T
์ ๊ฒฝ๊ณ๋ฅผ ์ฐ๊ฒฐํ๊ธฐ๋ฅผ ์ํ์ง๋ง ํด๋น ์์ค์์๋ 'ast
์๋ช
์ด ์์ผ๋ฉฐ $#๋ฅผ ์ ํํ๊ณ ์ถ์ง ์์ต๋๋ค T: 'static
(๊ทธ๋ฆฌ๊ณ for<'ast> T: 'ast
์ ๊ฐ์ ๊ฒ์ ์๋ํ์ง ์์).
ํธ์ง : ๋ด ์ฝ๋ ๊ธฐ๋ฐ ์ ๋ค๋ฅธ ๋ถ๋ถ์ GAT๋ฅผ ์ ์ฉํ๋ ค๊ณ ์๋ํ๋๋ฐ ์ค๋ฅ๊ฐ ํ๋๋ง ๋ฐ์ํฉ๋๋ค(ํ์ฌ๋ก์๋). ํ์ง๋ง ํด๋น ์ค๋ฅ๋ ์์ ์ธ๊ธํ ๋ฌธ์ ์ ๋ํ ์์ ์ฌํญ์ ๋ฐ๋ผ ๋ฌ๋ผ์ง๋ฏ๋ก ๊ฐ๋จํ ๊ณ ์น ์ ์์ต๋๋ค.
์๋ช
์ ํ์ ์ฐ๊ฒฐ๋ ์ ํ์ ์ถ๊ฐํ ์ ์์ต๋๋ค(ํน์ฑ ๋ฒ์ ์์ Self: 'ast
์ฌ์ฉ). ์ด ํ
์คํธ๋ ๋ค์๊ณผ ๊ฐ์ด ๋ณด์ฌ์ผ ํฉ๋๋ค.
https://github.com/rust-lang/rust/blob/db4826dd6ca48663a0b4c5ab0681258999017c7d/src/test/ui/generic-associated-types/iterable.rs#L6 -L21
๊ธ์, ๊ทธ๊ฒ์ ๋ถ๋ถ์ ์ผ๋ก ๋ง ์๋ํฉ๋๋ค ...์ค๋ฅ ๋ฉ์์ง
error[E0309]: the parameter type `T` may not live long enough
--> src/indention.rs:33:5
|
33 | type Output<'ast> where T: 'ast = &'ast T;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: consider adding an explicit lifetime bound `T: 'ast`...
= note: ...so that the type `T` will meet its required lifetime bounds
error[E0309]: the parameter type `T` may not live long enough
--> src/indention.rs:45:5
|
45 | type Output<'ast> where T: 'ast = crate::View<'ast, T, fn(&'ast T) -> T::Output<'ast>>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: consider adding an explicit lifetime bound `T: 'ast`...
= note: ...so that the type `T` will meet its required lifetime bounds
error[E0309]: the parameter type `T` may not live long enough
--> src/indention.rs:59:5
|
59 | / type Output<'ast2>
60 | | where
61 | | T: 'ast2,
62 | | O: 'ast2
63 | | = crate::View<'ast2, T, crate::view::MapViewFn<F, fn(F::Output<'ast2>) -> O::Output<'ast2>>>;
| |_____________________________________________________________________________________________________^
|
= help: consider adding an explicit lifetime bound `T: 'ast2`...
= note: ...so that the type `T` will meet its required lifetime bounds
error[E0309]: the parameter type `O` may not live long enough
--> src/indention.rs:59:5
|
59 | / type Output<'ast2>
60 | | where
61 | | T: 'ast2,
62 | | O: 'ast2
63 | | = crate::View<'ast2, T, crate::view::MapViewFn<F, fn(F::Output<'ast2>) -> O::Output<'ast2>>>;
| |_____________________________________________________________________________________________________^
|
= help: consider adding an explicit lifetime bound `O: 'ast2`...
= note: ...so that the type `O` will meet its required lifetime bounds
์ฝ๋๊ฐ ํ ๋จ๊ณ๋ฅผ ํต๊ณผํ ๊ฒ์ฒ๋ผ ๋ณด์
๋๋ค(์ด์ ์๋ ์ ์ฌํ ์ค๋ฅ๋ก ์ค๋ฅ๊ฐ ๋ฐ์ํ์ง๋ง ๊ทธ ์ฌ์ด์ E0107
๋ก๋ง ๊ตฌ์ฑ๋ ๋ ๋ค๋ฅธ ๋ฒ์ฃผ์ ์ค๋ฅ๊ฐ ๋ํ๋จ) hm.
ํธ์ง : ์ฒซ ๋ฒ์งธ ๋ฌธ์ฅ( where Self: 'ast
)์ ๋์ณค์ต๋๋ค. ์ง๊ธ์ ๊ทธ ๋ถ๋ถ์ด ์์ ๋์์ต๋๋ค. ๋๋ ๊ณ์ํ๋ ค๊ณ ๋
ธ๋ ฅํ๋ค.
์ถ๊ฐ ์ปจํ
์คํธ
์ข์, ๋ค์ ์ค๋ํซ:
impl<'ast, T, F, O> AsUnindented for crate::View<'ast, T, F>
where
Self: Clone,
F: crate::view::ViewFn<T, Output = &'ast O>,
O: AsUnindented + 'ast,
{
type Output<'ast2>
where
T: 'ast2,
= crate::View<'ast, T, crate::view::MapViewFn<F, fn(&'ast O) -> O::Output<'ast>>>;
#[inline]
fn as_unindented<'ast2>(&'ast2 self) -> Self::Output<'ast2> {
self.clone().map::<for<'x> fn(&'x O) -> O::Output<'x>, _>(O::as_unindented)
}
}
์ค๋ฅ:
error[E0631]: type mismatch in function arguments
--> src/indention.rs:66:67
|
66 | self.clone().map::<for<'x> fn(&'x O) -> O::Output<'x>, _>(O::as_unindented)
| ^^^^^^^^^^^^^^^^
| |
| expected signature of `for<'x> fn(<F as view::ViewFn<T>>::Output<'x>) -> _`
| found signature of `for<'x> fn(&'x O) -> _`
<F as view::ViewFn<T>>::Output<'x> ==> &'ast O
์ &'x O
๊ฐ ๊ฐ์ง ์๋ค๋ ๊ฒ์ ์๊ณ ์์ง๋ง ์์ ํ๋ ๋ฐฉ๋ฒ์ ๋ชจ๋ฆ
๋๋ค(์ปดํ์ผ๋ฌ๋ ๋ฐ์ธ๋ฉ๋ F: for<'x> crate::view::ViewFn<T, Output = &'x O>
์ ํ์ฉํ์ง ์์ต๋๋ค).
๋ค๋ฅธ ์๋ ์ค๋ฅ:
error[E0582]: binding for associated type `Output` references lifetime `'x`, which does not appear in the trait input types
--> src/indention.rs:56:39
|
56 | F: for<'x> crate::view::ViewFn<T, Output = &'x O>,
| ^^^^^^^^^^^^^^
๋๋ ํน์ฑ ์ถ๋ ฅ ์ ํ ํ ๋น์์ forall<'x>
๊ฒฝ๊ณ๋ฅผ ํํํ๋ ๋ฐฉ๋ฒ์ ๋ชจ๋ฆ
๋๋ค. ์๋ฅผ ๋ค์ด
where
F: crate::view::ViewFn<T, for<'x> Output<'x> = &'x O>,
๊ตฌ๋ฌธ ๋ถ์์กฐ์ฐจ ํ์ง ์์ต๋๋ค(" +
, ,
, ::
๋๋ >
, =
๋ฐ๊ฒฌ๋จ ").
self.clone().map
์ ํน์ฑ ์ถ๋ ฅ ์ ํ์ด ์ค์ ๋ก O::as_unindented
์ ์ ํ์
๋๊น, ์ฆ ๋งต์ ์ธ์ ์ ํ
crate::View
๊ฐ ๋ฌด์์ธ์ง ๋ชจ๋ฅด์ง๋ง map
ํจ์๋ ๋ค๋ฅธ ์ธ์๋ฅผ ์์ํ ์ ์์ผ๋ฏ๋ก ์ ํ์ด ์ผ์นํ์ง ์์ต๋๋ค.
@sighoya ์ด์ ๊ฒ์๋ฌผ์์ ์ ์ฅ์๋ฅผ ์ฐ๊ฒฐํ์ต๋๋ค. ์ฌ๊ธฐ์ crate::view::ViewFn::map
์ impl์ ๋ํ ์ง์ ๋งํฌ๊ฐ ์์ต๋๋ค.
์ปดํ์ผ๋ฌ๋ ์ด์ ๋ํด ๋ฌด์์ด๋ผ๊ณ ๋งํฉ๋๊น?:
where
for<'x> F: crate::view::ViewFn<T, Output<'x> = &'x O>,
(์์ง) ๊ตฌ๋ฌธ ๋ถ์ํ์ง ์์ต๋๋ค.
@matthewjasper ,
Rust Nomicon ์์ ๋ค์์ด ๊ตฌ๋ฌธ ๋ถ์๋ฉ๋๋ค.
where for<'a> F: Fn(&'a (u8, u16)) -> &'a u8,
Output<'x> = &'x 0>
๋ฅผ ์ฌ์ฉํ์ฌ ๊ตฌ๋ฌธ ๋ถ์ํ์ง ์์ต๋๊น?
์, Output<'x>=...
๋ ํด๋น ์์น์์ ๊ตฌ๋ฌธ ๋ถ์ํ์ง ์์ต๋๋ค.
Rustc 1.46.0-nightly
๋ก ๋ ์ด์ ์ปดํ์ผ๋์ง ์๋ create, grdf ๊ฐ ์์ต๋๋ค. ์ต๊ทผ GAT์ ๊ด๋ จํ์ฌ ๋ณ๊ฒฝ๋ ์ฌํญ์ด ์์ต๋๊น?
๋ด ๊ฒฝ์ฐ๋ ์ฒ์๋ถํฐ ์๋ํ๊ฒ ํ๊ธฐ ์ํด ํธ๋ฆญ์ ์ฌ์ฉํด์ผ ํ๊ธฐ ๋๋ฌธ์ ์ฝ๊ฐ ์ด์ํฉ๋๋ค. ๋๋ ๋ณธ์ง์ ์ผ๋ก ์ฐ๊ด๋ ๋ฐ๋ณต์ ์ ํ๊ณผ ํจ๊ป Graph
ํน์ฑ์ ๊ฐ์ง๊ณ ์์ต๋๋ค. ์๋ํ๋๋ก ํ๊ธฐ ์ํด ๋ชจ๋ ๋ฐ๋ณต์๋ฅผ ๋ค๋ฅธ ํน์ฑ Iter
์ ๋ฐฐ์นํ์ต๋๋ค.
pub trait Iter<'a, T: 'a> {
type Triples: Iterator<Item = Triple<&'a T>>;
type Subjects: Iterator<Item = (&'a T, Self::Predicates)>;
type Predicates: Iterator<Item = (&'a T, Self::Objects)>;
type Objects: Iterator<Item = &'a T>;
}
pub trait Graph<T = crate::Term> {
/// Iterators.
type Iter<'a>: Iter<'a, T>;
...
}
์ง๊ธ๊น์ง ์ ์๋ํ๋ Graph
๊ตฌํ์ด ํ๋ ์์ต๋๋ค.
impl<'a, T: 'a + Hash + Eq> crate::Iter<'a, T> for Iterators {
type Objects = Objects<'a, T>;
type Predicates = Predicates<'a, T>;
type Subjects = Subjects<'a, T>;
type Triples = Iter<'a, T>;
}
impl<T: Hash + Eq> crate::Graph<T> for HashGraph<T> {
type Iter<'a> = Iterators;
...
}
์ด์ Rustc๋ฅผ ์ ๋ฐ์ดํธํ์ผ๋ฏ๋ก ๋ค์๊ณผ ๊ฐ์ด ์คํจํฉ๋๋ค.
error[E0309]: the parameter type `T` may not live long enough
--> src/hash_dataset.rs:50:2
|
50 | type Iter<'a> = Iterators;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: consider adding an explicit lifetime bound `T: 'a`...
= note: ...so that the type `T` will meet its required lifetime bounds
T
๊ฐ ์ด๋ฏธ Iter
'a
์ ๋ฌถ์ฌ ์๊ธฐ ๋๋ฌธ์ ์ด๊ฒ์ ๋์๊ฒ ๋ณ๋ก ์๋ฏธ๊ฐ ์์ต๋๋ค ...
์๊ฒ ์ต๋๋ค. where
๊ฒฝ๊ณ๋ฅผ ์ถ๊ฐํ์ฌ ๋ค์ ์๋ํ๊ฒ ํ์ต๋๋ค.
ํน์ฑ์์:
type Iter<'a>: Iter<'a, T> where T: 'a;
๊ทธ๋ฆฌ๊ณ ๊ตฌํ์์:
type Iter<'a> where T: 'a = Iterators;
๊ทธ๋ฌ๋ ํนํ ๊ตฌํ์์ where
๊ฒฝ๊ณ์ ์ ํํ ์๋ฏธ๋ฅผ ์ดํดํ์ง ๋ชปํฉ๋๋ค(์ฒ์ ๋ณธ ๊ฒฝ์ฐ). ๋ํ ์ด์ ์ ์๋ํ ์ด์ ๋ ๋ง์ฐฌ๊ฐ์ง์
๋๋ค.
ํธ์ง: ๋๋ ์ฌ์ง์ด ๋ด ๊ณ ์ฝํ ํดํน์ ์ ๊ฑฐํ๊ณ ๊ด๋ จ ๋ฐ๋ณต์๋ฅผ ํน์ฑ ์์ฒด์ ๋ฃ์ ์ ์์์ต๋๋ค.
@DutchGhost๊ฐ ์ ๊ธฐํ ๋ ๋ง์ ์ฐจ๋จ ๋ฌธ์ ์ถ๊ฐ
https://github.com/rust-lang/rust/issues/74684๋ ์ถ๊ฐํ ์ ์์ต๋๋ค. :)
๋๋ ๊ธ์ ์ฐ๋ ๊ฒ์ ์ข์ํ์ง ์์ต๋๋ค. ์๋๋ฌ ์ฃผ์ธ์ . ๊ทธ๋ฌ๋ ์ด ๊ธฐ๋ฅ์ ์ด๋ฏธ ๊ฑฐ์ 3๋ ๋์ ์ค๋จ๋์์ผ๋ฉฐ ๊ฐ์ฅ ์ํ๋ ์ ๊ธฐ๋ฅ ์ค ํ๋๋ก ์์๋ฅผ ๋งค๊น๋๋ค.
์ฐ๋ฆฌ๋ ์ด๋์ ์์ต๋๊น? ๊ฐ์ฅ ์ต๊ทผ ์ํ ์์ฝ์ 2018๋ 6์ @LukasKalbertodt ๊ฐ ์์ฑํ ๊ฒ์ ๋๋ค. "๋ฐฑ์ ํ" ๋ฅผ ๊ธฐ๋ค๋ฆฌ๊ณ ์์ต๋๊น?
์์งํ ๊ด์ฐฐ: ๋ด๊ฐ ์ํ๋ ๊ฑฐ์ ๋ชจ๋ GAT ์ฉ๋์๋ ์๋ช ๋งค๊ฐ๋ณ์๊ฐ ํ๋๋ง ํ์ํฉ๋๋ค. ์ถ์๋ ํ์ ์ ์ฉ ๋ฒ์ ์ GAT๊ฐ ์ ๊ณตํ๊ธฐ ๋ ๊ฐ๋จํ ๊น์?
https://github.com/rust-lang/rust/issues/44265#issuecomment -568247656์ (๋ค์ ๊ฐ๊ฒฐํ) ์ ๋ฐ์ดํธ์ ๋๋ค.
์ด RFC๊ฐ Monad
๋ฐ Functor
๋ฅผ ์ง์ ๊ฐ๋ฅํ๊ฒ ํฉ๋๊น? ์๋๋ฉด HKT์์ ํด์ผ ํ ์ผ์ด ๋ ์์ต๋๊น?
์ด RFC๊ฐ Monad์ Functor๋ฅผ ์ง์ ๊ฐ๋ฅํ๊ฒ ๋ง๋ค๊น์? ์๋๋ฉด HKT์์ ํด์ผ ํ ์ผ์ด ๋ ์์ต๋๊น?
@ibraheemdev RFC ์ํ
์ด๊ฒ์ ์ฌ๋๋ค์ด ๋ ๋์ ์ข ๋ฅ์ ์ ํ์ ๋ํด ์ด์ผ๊ธฐํ ๋ ์ํ๋ ๋ชจ๋ ๊ธฐ๋ฅ์ ์ถ๊ฐํ์ง ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, Monad์ ๊ฐ์ ํน์ฑ์ ํ์ฑํํ์ง ์์ต๋๋ค. ์ด๋ค ์ฌ๋๋ค์ ์ด๋ฌํ ๋ชจ๋ ๊ธฐ๋ฅ์ ํ ๋ฒ์ ํจ๊ป ๊ตฌํํ๋ ๊ฒ์ ์ ํธํ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ์ด ๊ธฐ๋ฅ์ ๋ค๋ฅธ ์ข ๋ฅ์ ๊ณ ๊ธ ๋คํ์ฑ๊ณผ ํธํ๋๋ฉฐ ์ด๋ค ์์ผ๋ก๋ ๊ตฌํ์ ๋ฐฉํดํ์ง ์์ต๋๋ค. ์ฌ์ค, ๋ถ๋ถ ์ ์ฉ๊ณผ ๊ฐ์ด ๋ค๋ฅธ ์ข ๋ฅ์ ๊ณ ๊ธ์๋ ์ํฅ์ ๋ฏธ์น ์ผ๋ถ ๊ตฌํ ์ธ๋ถ ์ฌํญ์ ํด๊ฒฐํจ์ผ๋ก์จ ๊ธธ์ ๋ฆ์ต๋๋ค.
@ibraheemdev : ์ ๋๋์ ๋ชจ๋๋์ ํํฐ๋ฅผ ๊ฐ๋ฅํ๊ฒ ๋ง๋๋ ๊ฐ์ฅ ๊ด์ฉ์ ์ธ ๋ฐฉ๋ฒ์ ์ ๋ค๋ฆญ ๊ด๋ จ ํน์ฑ ์ ๋์ ํ๋ ๊ฒ์ด์ง๋ง ์ ๋ค๋ฆญ ๊ด๋ จ ์ ํ์ ํ์คํ ์ ์ ์กฐ๊ฑด์ด๋ผ๋ ๊ฒ์ ๋๋ค.
GAT๊ฐ ํ์ํ์ง ์์ Monad
๊ฒฝ๋ก๊ฐ ์์ต๋๊น?
@ibraheemdev ๊ฐ์ ์ ์ผ๋ก ์, HKT๋ฅผ ์ง์ ๊ตฌํํ ๋ค์ ๋งจ ์์ Monad
ํธ๋ ์์ ๊ตฌํํ๋ ๊ฒ์ด ๊ฐ๋ฅํฉ๋๋ค. ๊ทธ๋ฌ๋ ๊ทธ ๋ฐฉํฅ์ผ๋ก๋ ์์
์ด ์งํ๋์ง ์์ผ๋ฉฐ ์๋ง๋ ์์ผ๋ก๋ ์์ ๊ฒ์
๋๋ค. ๊ทธ ์ ๊ทผ ๋ฐฉ์์ Rust๊ฐ ๊ฐ์ง๊ณ ์๋ ๋ฌธ์ ๋ฅผ ์ค์ ๋ก ํด๊ฒฐํ์ง ๋ชปํ๊ธฐ ๋๋ฌธ์
๋๋ค. https://twitter.com/withoutboats/status/1027702531361857536
์ด์ฉ๋ฉด ๋ด๊ฐ ํ๋ฆด ์๋ ์์ง๋ง GAT๋ ๋ค์๊ณผ ๊ฐ์ ๊ฒ์ ํ์ฉํ๋ค๊ณ ์๊ฐํฉ๋๋ค.
trait MonadFamily {
type Monad<T>;
fn pure<T>(inner: T) -> Self::Monad<T>;
fn bind<T, U, F: FnOnce(T) -> U>(this: Self::Monad<T>, f: F) -> Self::Monad<U>;
}
@ibraheemdev
GAT๊ฐ ํ์ํ์ง ์์
Monad
๊ฒฝ๋ก๊ฐ ์์ต๋๊น?
์, Rust์์ ๊ณ ๊ธ ์ ํ์ ์๋ฎฌ๋ ์ดํธํ๋ ๋ฐฉ๋ฒ์ ์ฐธ์กฐํ์ธ์. ์ง๊ธ์ ์์ ์ ์ธ ์ํ์์๋ ์๋ํฉ๋๋ค.
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
https://github.com/rust-lang/rust/issues/44265#issuecomment -568247656์ (๋ค์ ๊ฐ๊ฒฐํ) ์ ๋ฐ์ดํธ์ ๋๋ค.
67510์ ๊ตฌํํด์ผ ํ๋ ๋ง์ง๋ง ์ฃผ์ ICE/๋๋ฝ ๊ธฐ๋ฅ์ ๋๋ค.