diff --git a/crates/wasm-compose/src/encoding.rs b/crates/wasm-compose/src/encoding.rs index 7eb3fb52c4..a9bd70fa9d 100644 --- a/crates/wasm-compose/src/encoding.rs +++ b/crates/wasm-compose/src/encoding.rs @@ -813,8 +813,8 @@ impl<'a> TypeEncoder<'a> { index } - fn stream(&self, state: &mut TypeState<'a>, ty: ct::ComponentValType) -> u32 { - let ty = self.component_val_type(state, ty); + fn stream(&self, state: &mut TypeState<'a>, ty: Option) -> u32 { + let ty = ty.map(|ty| self.component_val_type(state, ty)); let index = state.cur.encodable.type_count(); state.cur.encodable.ty().defined_type().stream(ty); @@ -1255,9 +1255,7 @@ impl DependencyRegistrar<'_, '_> { | ComponentDefinedType::Enum(_) | ComponentDefinedType::Flags(_) | ComponentDefinedType::ErrorContext => {} - ComponentDefinedType::List(t) - | ComponentDefinedType::Option(t) - | ComponentDefinedType::Stream(t) => self.val_type(*t), + ComponentDefinedType::List(t) | ComponentDefinedType::Option(t) => self.val_type(*t), ComponentDefinedType::Own(r) | ComponentDefinedType::Borrow(r) => { self.ty(ComponentAnyTypeId::Resource(*r)) } @@ -1291,6 +1289,11 @@ impl DependencyRegistrar<'_, '_> { self.val_type(*ty); } } + ComponentDefinedType::Stream(ty) => { + if let Some(ty) = ty { + self.val_type(*ty); + } + } } } } diff --git a/crates/wasm-encoder/src/component/types.rs b/crates/wasm-encoder/src/component/types.rs index 44a877db2c..543bddbb33 100644 --- a/crates/wasm-encoder/src/component/types.rs +++ b/crates/wasm-encoder/src/component/types.rs @@ -680,7 +680,7 @@ impl ComponentDefinedTypeEncoder<'_> { } /// Define a `stream` type with the specified payload. - pub fn stream(self, payload: ComponentValType) { + pub fn stream(self, payload: Option) { self.0.push(0x66); payload.encode(self.0); } diff --git a/crates/wasm-encoder/src/reencode/component.rs b/crates/wasm-encoder/src/reencode/component.rs index 1ac94d68ca..c4b1d78945 100644 --- a/crates/wasm-encoder/src/reencode/component.rs +++ b/crates/wasm-encoder/src/reencode/component.rs @@ -804,7 +804,7 @@ pub mod component_utils { defined.future(t.map(|t| reencoder.component_val_type(t))); } wasmparser::ComponentDefinedType::Stream(t) => { - defined.stream(reencoder.component_val_type(t)); + defined.stream(t.map(|t| reencoder.component_val_type(t))); } wasmparser::ComponentDefinedType::ErrorContext => defined.error_context(), } diff --git a/crates/wasmparser/src/readers/component/types.rs b/crates/wasmparser/src/readers/component/types.rs index 512144951b..a56835fd82 100644 --- a/crates/wasmparser/src/readers/component/types.rs +++ b/crates/wasmparser/src/readers/component/types.rs @@ -508,7 +508,7 @@ pub enum ComponentDefinedType<'a> { /// A future type with the specified payload type. Future(Option), /// A stream type with the specified payload type. - Stream(ComponentValType), + Stream(Option), /// The error-context type. ErrorContext, } diff --git a/crates/wasmparser/src/validator/component.rs b/crates/wasmparser/src/validator/component.rs index 27e20ead84..4133bf4e34 100644 --- a/crates/wasmparser/src/validator/component.rs +++ b/crates/wasmparser/src/validator/component.rs @@ -759,7 +759,10 @@ impl ComponentState { .as_ref() .map(|ty| types.type_named_valtype(ty, set)) .unwrap_or(true), - ComponentDefinedType::Stream(ty) => types.type_named_valtype(ty, set), + ComponentDefinedType::Stream(ty) => ty + .as_ref() + .map(|ty| types.type_named_valtype(ty, set)) + .unwrap_or(true), } } @@ -1255,7 +1258,9 @@ impl ComponentState { let mut info = LoweringInfo::default(); info.requires_memory = true; - info.requires_realloc = payload_type.contains_ptr(types); + info.requires_realloc = payload_type + .map(|ty| ty.contains_ptr(types)) + .unwrap_or_default(); self.check_options(None, &info, &options, types, offset, features, true)?; self.core_funcs @@ -1439,7 +1444,7 @@ impl ComponentState { info.requires_memory = true; info.requires_realloc = payload_type .map(|ty| ty.contains_ptr(types)) - .unwrap_or(false); + .unwrap_or_default(); self.check_options(None, &info, &options, types, offset, features, true)?; self.core_funcs @@ -3291,7 +3296,8 @@ impl ComponentState { .transpose()?, )), crate::ComponentDefinedType::Stream(ty) => Ok(ComponentDefinedType::Stream( - self.create_component_val_type(ty, offset)?, + ty.map(|ty| self.create_component_val_type(ty, offset)) + .transpose()?, )), crate::ComponentDefinedType::ErrorContext => Ok(ComponentDefinedType::ErrorContext), } diff --git a/crates/wasmparser/src/validator/component_types.rs b/crates/wasmparser/src/validator/component_types.rs index 25f7dd8400..76ab1ff57b 100644 --- a/crates/wasmparser/src/validator/component_types.rs +++ b/crates/wasmparser/src/validator/component_types.rs @@ -1062,7 +1062,7 @@ pub enum ComponentDefinedType { /// A future type with the specified payload type. Future(Option), /// A stream type with the specified payload type. - Stream(ComponentValType), + Stream(Option), /// The error-context type. ErrorContext, } @@ -1950,9 +1950,7 @@ impl TypeAlloc { } } } - ComponentDefinedType::List(ty) - | ComponentDefinedType::Option(ty) - | ComponentDefinedType::Stream(ty) => { + ComponentDefinedType::List(ty) | ComponentDefinedType::Option(ty) => { self.free_variables_valtype(ty, set); } ComponentDefinedType::Result { ok, err } => { @@ -1971,6 +1969,11 @@ impl TypeAlloc { self.free_variables_valtype(ty, set); } } + ComponentDefinedType::Stream(ty) => { + if let Some(ty) = ty { + self.free_variables_valtype(ty, set); + } + } } } @@ -2094,9 +2097,9 @@ impl TypeAlloc { .map(|t| self.type_named_valtype(t, set)) .unwrap_or(true) } - ComponentDefinedType::List(ty) - | ComponentDefinedType::Option(ty) - | ComponentDefinedType::Stream(ty) => self.type_named_valtype(ty, set), + ComponentDefinedType::List(ty) | ComponentDefinedType::Option(ty) => { + self.type_named_valtype(ty, set) + } // own/borrow themselves don't have to be named, but the resource // they refer to must be named. @@ -2108,6 +2111,11 @@ impl TypeAlloc { .as_ref() .map(|ty| self.type_named_valtype(ty, set)) .unwrap_or(true), + + ComponentDefinedType::Stream(ty) => ty + .as_ref() + .map(|ty| self.type_named_valtype(ty, set)) + .unwrap_or(true), } } @@ -2277,9 +2285,7 @@ where } } } - ComponentDefinedType::List(ty) - | ComponentDefinedType::Option(ty) - | ComponentDefinedType::Stream(ty) => { + ComponentDefinedType::List(ty) | ComponentDefinedType::Option(ty) => { any_changed |= self.remap_valtype(ty, map); } ComponentDefinedType::Result { ok, err } => { @@ -2293,7 +2299,7 @@ where ComponentDefinedType::Own(id) | ComponentDefinedType::Borrow(id) => { any_changed |= self.remap_resource_id(id, map); } - ComponentDefinedType::Future(ty) => { + ComponentDefinedType::Future(ty) | ComponentDefinedType::Stream(ty) => { if let Some(ty) = ty { any_changed |= self.remap_valtype(ty, map); } @@ -3234,9 +3240,14 @@ impl<'a> SubtypeCx<'a> { (Some(_), None) => bail!(offset, "expected future type to not be present"), }, (Future(_), b) => bail!(offset, "expected {}, found future", b.desc()), - (Stream(a), Stream(b)) => self - .component_val_type(a, b, offset) - .with_context(|| "type mismatch in stream"), + (Stream(a), Stream(b)) => match (a, b) { + (None, None) => Ok(()), + (Some(a), Some(b)) => self + .component_val_type(a, b, offset) + .with_context(|| "type mismatch in stream"), + (None, Some(_)) => bail!(offset, "expected stream type, but found none"), + (Some(_), None) => bail!(offset, "expected stream type to not be present"), + }, (Stream(_), b) => bail!(offset, "expected {}, found stream", b.desc()), (ErrorContext, ErrorContext) => Ok(()), (ErrorContext, b) => bail!(offset, "expected {}, found error-context", b.desc()), diff --git a/crates/wasmprinter/src/component.rs b/crates/wasmprinter/src/component.rs index 0a40fe163f..24a2cbfd16 100644 --- a/crates/wasmprinter/src/component.rs +++ b/crates/wasmprinter/src/component.rs @@ -240,10 +240,14 @@ impl Printer<'_, '_> { Ok(()) } - fn print_stream_type(&mut self, state: &State, ty: ComponentValType) -> Result<()> { + fn print_stream_type(&mut self, state: &State, ty: Option) -> Result<()> { self.start_group("stream")?; - self.result.write_str(" ")?; - self.print_component_val_type(state, &ty)?; + + if let Some(ty) = ty { + self.result.write_str(" ")?; + self.print_component_val_type(state, &ty)?; + } + self.end_group()?; Ok(()) diff --git a/crates/wast/src/component/binary.rs b/crates/wast/src/component/binary.rs index 856b50d7ff..2bf5e773fe 100644 --- a/crates/wast/src/component/binary.rs +++ b/crates/wast/src/component/binary.rs @@ -133,7 +133,7 @@ fn encode_defined_type(encoder: ComponentDefinedTypeEncoder, ty: &ComponentDefin } ComponentDefinedType::Own(i) => encoder.own((*i).into()), ComponentDefinedType::Borrow(i) => encoder.borrow((*i).into()), - ComponentDefinedType::Stream(s) => encoder.stream(s.element.as_ref().into()), + ComponentDefinedType::Stream(s) => encoder.stream(s.element.as_deref().map(Into::into)), ComponentDefinedType::Future(f) => encoder.future(f.element.as_deref().map(Into::into)), } } diff --git a/crates/wast/src/component/expand.rs b/crates/wast/src/component/expand.rs index 2df745f0c9..5f171feec5 100644 --- a/crates/wast/src/component/expand.rs +++ b/crates/wast/src/component/expand.rs @@ -762,7 +762,9 @@ impl<'a> Expander<'a> { } ComponentDefinedType::Own(_) | ComponentDefinedType::Borrow(_) => {} ComponentDefinedType::Stream(t) => { - self.expand_component_val_ty(&mut t.element); + if let Some(ty) = &mut t.element { + self.expand_component_val_ty(ty); + } } ComponentDefinedType::Future(t) => { if let Some(ty) = &mut t.element { diff --git a/crates/wast/src/component/resolve.rs b/crates/wast/src/component/resolve.rs index c488b58175..c782a2eb77 100644 --- a/crates/wast/src/component/resolve.rs +++ b/crates/wast/src/component/resolve.rs @@ -553,7 +553,9 @@ impl<'a> Resolver<'a> { self.resolve_ns(t, Ns::Type)?; } ComponentDefinedType::Stream(s) => { - self.component_val_type(&mut s.element)?; + if let Some(ty) = &mut s.element { + self.component_val_type(ty)?; + } } ComponentDefinedType::Future(f) => { if let Some(ty) = &mut f.element { diff --git a/crates/wast/src/component/types.rs b/crates/wast/src/component/types.rs index abefa1d10d..23951f2164 100644 --- a/crates/wast/src/component/types.rs +++ b/crates/wast/src/component/types.rs @@ -694,14 +694,14 @@ impl<'a> Parse<'a> for ResultType<'a> { #[derive(Debug)] pub struct Stream<'a> { /// The element type of the stream. - pub element: Box>, + pub element: Option>>, } impl<'a> Parse<'a> for Stream<'a> { fn parse(parser: Parser<'a>) -> Result { parser.parse::()?; Ok(Self { - element: Box::new(parser.parse()?), + element: parser.parse::>()?.map(Box::new), }) } } diff --git a/crates/wit-component/src/encoding.rs b/crates/wit-component/src/encoding.rs index 6c1b3a25b8..75852bc18f 100644 --- a/crates/wit-component/src/encoding.rs +++ b/crates/wit-component/src/encoding.rs @@ -1368,7 +1368,15 @@ impl<'a> EncodingState<'a> { else { unreachable!() }; - let options = options(self, vec![*payload_type], vec![])?; + let options = options( + self, + if let Some(payload_type) = payload_type { + vec![*payload_type] + } else { + vec![] + }, + vec![], + )?; self.component.stream_write(type_index, options) } PayloadFuncKind::StreamRead => { @@ -1376,7 +1384,15 @@ impl<'a> EncodingState<'a> { else { unreachable!() }; - let options = options(self, vec![], vec![*payload_type])?; + let options = options( + self, + vec![], + if let Some(payload_type) = payload_type { + vec![*payload_type] + } else { + vec![] + }, + )?; self.component.stream_read(type_index, options) } } @@ -1443,8 +1459,8 @@ impl<'a> EncodingState<'a> { fn owner(resolve: &Resolve, ty: TypeId) -> Option { let def = &resolve.types[ty]; match &def.kind { - TypeDefKind::Future(Some(Type::Id(ty))) => owner(resolve, *ty), - TypeDefKind::Stream(Type::Id(ty)) => owner(resolve, *ty), + TypeDefKind::Future(Some(Type::Id(ty))) + | TypeDefKind::Stream(Some(Type::Id(ty))) => owner(resolve, *ty), _ => match &def.owner { TypeOwner::World(_) | TypeOwner::None => None, TypeOwner::Interface(id) => Some(*id), diff --git a/crates/wit-component/src/encoding/types.rs b/crates/wit-component/src/encoding/types.rs index 1ed436640c..cdf2e89356 100644 --- a/crates/wit-component/src/encoding/types.rs +++ b/crates/wit-component/src/encoding/types.rs @@ -322,8 +322,12 @@ pub trait ValtypeEncoder<'a> { Ok(ComponentValType::Type(index)) } - fn encode_stream(&mut self, resolve: &'a Resolve, payload: &Type) -> Result { - let ty = self.encode_valtype(resolve, payload)?; + fn encode_stream( + &mut self, + resolve: &'a Resolve, + payload: &Option, + ) -> Result { + let ty = self.encode_optional_valtype(resolve, payload.as_ref())?; let (index, encoder) = self.defined_type(); encoder.stream(ty); Ok(ComponentValType::Type(index)) diff --git a/crates/wit-component/src/printing.rs b/crates/wit-component/src/printing.rs index 5ea9397739..9c6e716501 100644 --- a/crates/wit-component/src/printing.rs +++ b/crates/wit-component/src/printing.rs @@ -584,9 +584,13 @@ impl WitPrinter { } } TypeDefKind::Stream(ty) => { - self.output.push_str("stream<"); - self.print_type_name(resolve, ty)?; - self.output.push_str(">"); + if let Some(ty) = ty { + self.output.push_str("stream<"); + self.print_type_name(resolve, ty)?; + self.output.push_str(">"); + } else { + self.output.push_str("stream"); + } } TypeDefKind::ErrorContext => self.output.push_str("error-context"), TypeDefKind::Unknown => unreachable!(), @@ -758,7 +762,7 @@ impl WitPrinter { self.declare_future(resolve, ty.name.as_deref(), inner.as_ref())? } TypeDefKind::Stream(inner) => { - self.declare_stream(resolve, ty.name.as_deref(), inner)? + self.declare_stream(resolve, ty.name.as_deref(), inner.as_ref())? } TypeDefKind::ErrorContext => self.declare_error_context(ty.name.as_deref())?, TypeDefKind::Unknown => unreachable!(), @@ -957,16 +961,23 @@ impl WitPrinter { Ok(()) } - fn declare_stream(&mut self, resolve: &Resolve, name: Option<&str>, ty: &Type) -> Result<()> { + fn declare_stream( + &mut self, + resolve: &Resolve, + name: Option<&str>, + ty: Option<&Type>, + ) -> Result<()> { if let Some(name) = name { self.output.keyword("type"); self.output.str(" "); self.print_name_type(name, TypeKind::Stream); self.output.str(" = "); self.output.ty("stream", TypeKind::BuiltIn); - self.output.str("<"); - self.print_type_name(resolve, ty)?; - self.output.str(">"); + if let Some(ty) = ty { + self.output.str("<"); + self.print_type_name(resolve, ty)?; + self.output.str(">"); + } self.output.semicolon(); } diff --git a/crates/wit-encoder/src/from_parser.rs b/crates/wit-encoder/src/from_parser.rs index a31c34a10b..32c97cc937 100644 --- a/crates/wit-encoder/src/from_parser.rs +++ b/crates/wit-encoder/src/from_parser.rs @@ -232,7 +232,7 @@ impl<'a> Converter<'a> { TypeDefKind::Type(Type::future(self.convert_option_type(ty))) } wit_parser::TypeDefKind::Stream(ty) => { - TypeDefKind::Type(Type::stream(self.convert_type(ty))) + TypeDefKind::Type(Type::stream(self.convert_option_type(ty))) } wit_parser::TypeDefKind::ErrorContext => TypeDefKind::Type(Type::ErrorContext), // all the following are just `type` declarations @@ -309,7 +309,7 @@ impl<'a> Converter<'a> { Type::future(self.convert_option_type(type_)) } wit_parser::TypeDefKind::Stream(type_) => { - Type::stream(self.convert_type(type_)) + Type::stream(self.convert_option_type(type_)) } wit_parser::TypeDefKind::ErrorContext => Type::ErrorContext, wit_parser::TypeDefKind::Record(_) diff --git a/crates/wit-encoder/src/ty.rs b/crates/wit-encoder/src/ty.rs index 583e39ab56..afe4891a41 100644 --- a/crates/wit-encoder/src/ty.rs +++ b/crates/wit-encoder/src/ty.rs @@ -28,7 +28,7 @@ pub enum Type { List(Box), Tuple(Tuple), Future(Option>), - Stream(Box), + Stream(Option>), ErrorContext, Named(Ident), } @@ -66,8 +66,8 @@ impl Type { pub fn future(type_: Option) -> Self { Type::Future(type_.map(Box::new)) } - pub fn stream(type_: Type) -> Self { - Type::Stream(Box::new(type_)) + pub fn stream(type_: Option) -> Self { + Type::Stream(type_.map(Box::new)) } pub fn named(name: impl Into) -> Self { Type::Named(name.into()) @@ -123,7 +123,10 @@ impl Display for Type { Type::Future(Some(type_)) => { write!(f, "future<{type_}>") } - Type::Stream(type_) => { + Type::Stream(None) => { + write!(f, "stream") + } + Type::Stream(Some(type_)) => { write!(f, "stream<{type_}>") } Type::ErrorContext => write!(f, "error-context"), diff --git a/crates/wit-parser/src/ast.rs b/crates/wit-parser/src/ast.rs index b3e3033e58..727d248a3d 100644 --- a/crates/wit-parser/src/ast.rs +++ b/crates/wit-parser/src/ast.rs @@ -898,7 +898,7 @@ struct Result_<'a> { struct Stream<'a> { span: Span, - ty: Box>, + ty: Option>>, } struct NamedFunc<'a> { @@ -1404,14 +1404,15 @@ impl<'a> Type<'a> { } // stream + // stream Some((span, Token::Stream)) => { - tokens.expect(Token::LessThan)?; - let ty = Type::parse(tokens)?; - tokens.expect(Token::GreaterThan)?; - Ok(Type::Stream(Stream { - span, - ty: Box::new(ty), - })) + let mut ty = None; + + if tokens.eat(Token::LessThan)? { + ty = Some(Box::new(Type::parse(tokens)?)); + tokens.expect(Token::GreaterThan)?; + }; + Ok(Type::Stream(Stream { span, ty })) } // error-context diff --git a/crates/wit-parser/src/ast/resolve.rs b/crates/wit-parser/src/ast/resolve.rs index b38d658866..4ddca1b999 100644 --- a/crates/wit-parser/src/ast/resolve.rs +++ b/crates/wit-parser/src/ast/resolve.rs @@ -95,7 +95,7 @@ enum Key { Option(Type), Result(Option, Option), Future(Option), - Stream(Type), + Stream(Option), ErrorContext, } @@ -1255,7 +1255,9 @@ impl<'a> Resolver<'a> { ast::Type::Future(t) => { TypeDefKind::Future(self.resolve_optional_type(t.ty.as_deref(), stability)?) } - ast::Type::Stream(s) => TypeDefKind::Stream(self.resolve_type(&s.ty, stability)?), + ast::Type::Stream(s) => { + TypeDefKind::Stream(self.resolve_optional_type(s.ty.as_deref(), stability)?) + } ast::Type::ErrorContext(_) => TypeDefKind::ErrorContext, }) } @@ -1325,10 +1327,10 @@ impl<'a> Resolver<'a> { find_in_type(types, Type::Id(*id)) } TypeDefKind::Tuple(t) => t.types.iter().find_map(|ty| find_in_type(types, *ty)), - TypeDefKind::List(ty) | TypeDefKind::Stream(ty) | TypeDefKind::Option(ty) => { - find_in_type(types, *ty) + TypeDefKind::List(ty) | TypeDefKind::Option(ty) => find_in_type(types, *ty), + TypeDefKind::Future(ty) | TypeDefKind::Stream(ty) => { + ty.as_ref().and_then(|ty| find_in_type(types, *ty)) } - TypeDefKind::Future(ty) => ty.as_ref().and_then(|ty| find_in_type(types, *ty)), TypeDefKind::Result(r) => { r.ok.as_ref() .and_then(|ty| find_in_type(types, *ty)) @@ -1657,9 +1659,9 @@ fn collect_deps<'a>(ty: &ast::Type<'a>, deps: &mut Vec>) { } } } - ast::Type::Option(ast::Option_ { ty, .. }) - | ast::Type::List(ast::List { ty, .. }) - | ast::Type::Stream(ast::Stream { ty, .. }) => collect_deps(ty, deps), + ast::Type::Option(ast::Option_ { ty, .. }) | ast::Type::List(ast::List { ty, .. }) => { + collect_deps(ty, deps) + } ast::Type::Result(r) => { if let Some(ty) = &r.ok { collect_deps(ty, deps); @@ -1673,5 +1675,10 @@ fn collect_deps<'a>(ty: &ast::Type<'a>, deps: &mut Vec>) { collect_deps(t, deps) } } + ast::Type::Stream(s) => { + if let Some(t) = &s.ty { + collect_deps(t, deps) + } + } } } diff --git a/crates/wit-parser/src/decoding.rs b/crates/wit-parser/src/decoding.rs index 0dbb04147d..2cc0b406d2 100644 --- a/crates/wit-parser/src/decoding.rs +++ b/crates/wit-parser/src/decoding.rs @@ -1401,7 +1401,9 @@ impl WitPackageDecoder<'_> { ty.as_ref().map(|ty| self.convert_valtype(ty)).transpose()?, )), - ComponentDefinedType::Stream(ty) => Ok(TypeDefKind::Stream(self.convert_valtype(ty)?)), + ComponentDefinedType::Stream(ty) => Ok(TypeDefKind::Stream( + ty.as_ref().map(|ty| self.convert_valtype(ty)).transpose()?, + )), ComponentDefinedType::ErrorContext => Ok(TypeDefKind::ErrorContext), } @@ -1693,7 +1695,11 @@ impl Registrar<'_> { TypeDefKind::Type(Type::Id(_)) => return Ok(()), _ => bail!("expected a stream"), }; - self.valtype(payload, ty) + match (payload, ty) { + (Some(a), Some(b)) => self.valtype(a, b), + (None, None) => Ok(()), + _ => bail!("disagreement on stream payload"), + } } // These have no recursive structure so they can bail out. diff --git a/crates/wit-parser/src/lib.rs b/crates/wit-parser/src/lib.rs index a3370cf5ec..3e11bba84a 100644 --- a/crates/wit-parser/src/lib.rs +++ b/crates/wit-parser/src/lib.rs @@ -570,7 +570,7 @@ pub enum TypeDefKind { Result(Result_), List(Type), Future(Option), - Stream(Type), + Stream(Option), ErrorContext, Type(Type), @@ -1140,7 +1140,9 @@ fn find_futures_and_streams(resolve: &Resolve, ty: Type, results: &mut Vec { - find_futures_and_streams(resolve, *ty, results); + if let Some(ty) = ty { + find_futures_and_streams(resolve, *ty, results); + } results.push(id); } TypeDefKind::Unknown => unreachable!(), @@ -1246,7 +1248,7 @@ mod test { }); let t2 = resolve.types.alloc(TypeDef { name: None, - kind: TypeDefKind::Stream(Type::U32), + kind: TypeDefKind::Stream(Some(Type::U32)), owner: TypeOwner::None, docs: Docs::default(), stability: Stability::Unknown, diff --git a/crates/wit-parser/src/live.rs b/crates/wit-parser/src/live.rs index 84e2ebf8b7..2027bd1b80 100644 --- a/crates/wit-parser/src/live.rs +++ b/crates/wit-parser/src/live.rs @@ -130,7 +130,7 @@ pub trait TypeIdVisitor { | TypeDefKind::List(t) | TypeDefKind::Option(t) | TypeDefKind::Future(Some(t)) - | TypeDefKind::Stream(t) => self.visit_type(resolve, t), + | TypeDefKind::Stream(Some(t)) => self.visit_type(resolve, t), TypeDefKind::Handle(handle) => match handle { crate::Handle::Own(ty) => self.visit_type_id(resolve, *ty), crate::Handle::Borrow(ty) => self.visit_type_id(resolve, *ty), @@ -164,7 +164,8 @@ pub trait TypeIdVisitor { TypeDefKind::ErrorContext | TypeDefKind::Flags(_) | TypeDefKind::Enum(_) - | TypeDefKind::Future(None) => {} + | TypeDefKind::Future(None) + | TypeDefKind::Stream(None) => {} TypeDefKind::Unknown => unreachable!(), } } diff --git a/crates/wit-parser/src/resolve.rs b/crates/wit-parser/src/resolve.rs index d1f40381ab..590097813e 100644 --- a/crates/wit-parser/src/resolve.rs +++ b/crates/wit-parser/src/resolve.rs @@ -3019,7 +3019,9 @@ impl Remap { } } } - Option(t) | List(t) | Stream(t) => self.update_ty(resolve, t, span)?, + Option(t) | List(t) | Future(Some(t)) | Stream(Some(t)) => { + self.update_ty(resolve, t, span)? + } Result(r) => { if let Some(ty) = &mut r.ok { self.update_ty(resolve, ty, span)?; @@ -3028,7 +3030,6 @@ impl Remap { self.update_ty(resolve, ty, span)?; } } - Future(Some(t)) => self.update_ty(resolve, t, span)?, ErrorContext => {} // Note that `update_ty` is specifically not used here as typedefs @@ -3039,7 +3040,7 @@ impl Remap { Type(_) => {} // nothing to do for these as they're just names or empty - Flags(_) | Enum(_) | Future(None) => {} + Flags(_) | Enum(_) | Future(None) | Stream(None) => {} Unknown => unreachable!(), } @@ -3422,13 +3423,15 @@ impl Remap { TypeDefKind::Enum(_) => false, TypeDefKind::List(ty) | TypeDefKind::Future(Some(ty)) - | TypeDefKind::Stream(ty) + | TypeDefKind::Stream(Some(ty)) | TypeDefKind::Option(ty) => self.type_has_borrow(resolve, ty), TypeDefKind::Result(r) => [&r.ok, &r.err] .iter() .filter_map(|t| t.as_ref()) .any(|t| self.type_has_borrow(resolve, t)), - TypeDefKind::Future(None) | TypeDefKind::ErrorContext => false, + TypeDefKind::Future(None) | TypeDefKind::Stream(None) | TypeDefKind::ErrorContext => { + false + } TypeDefKind::Unknown => unreachable!(), } } diff --git a/crates/wit-parser/src/resolve/clone.rs b/crates/wit-parser/src/resolve/clone.rs index 4c8c18ef44..1f7dc54381 100644 --- a/crates/wit-parser/src/resolve/clone.rs +++ b/crates/wit-parser/src/resolve/clone.rs @@ -110,7 +110,7 @@ impl<'a> Cloner<'a> { TypeDefKind::Handle(Handle::Own(ty) | Handle::Borrow(ty)) => { self.type_id(ty); } - TypeDefKind::Option(ty) | TypeDefKind::List(ty) | TypeDefKind::Stream(ty) => { + TypeDefKind::Option(ty) | TypeDefKind::List(ty) => { self.ty(ty); } TypeDefKind::Tuple(list) => { @@ -138,8 +138,8 @@ impl<'a> Cloner<'a> { self.ty(err); } } - TypeDefKind::Future(f) => { - if let Some(ty) = f { + TypeDefKind::Future(ty) | TypeDefKind::Stream(ty) => { + if let Some(ty) = ty { self.ty(ty); } } diff --git a/crates/wit-parser/tests/ui/streams-and-futures.wit b/crates/wit-parser/tests/ui/streams-and-futures.wit index de023fdcf7..72d5f3dce0 100644 --- a/crates/wit-parser/tests/ui/streams-and-futures.wit +++ b/crates/wit-parser/tests/ui/streams-and-futures.wit @@ -9,6 +9,7 @@ interface streams-and-futures { resource r1; type t6 = stream; type t7 = future>; + type t8 = stream; foo: func(x: stream, y: t6) -> future, string>>; } diff --git a/crates/wit-parser/tests/ui/streams-and-futures.wit.json b/crates/wit-parser/tests/ui/streams-and-futures.wit.json index a422a21a17..a0bc2d958a 100644 --- a/crates/wit-parser/tests/ui/streams-and-futures.wit.json +++ b/crates/wit-parser/tests/ui/streams-and-futures.wit.json @@ -11,7 +11,8 @@ "t5": 8, "r1": 9, "t6": 11, - "t7": 13 + "t7": 13, + "t8": 14 }, "functions": { "foo": { @@ -20,7 +21,7 @@ "params": [ { "name": "x", - "type": 14 + "type": 15 }, { "name": "y", @@ -29,7 +30,7 @@ ], "results": [ { - "type": 17 + "type": 18 } ] } @@ -155,6 +156,15 @@ "interface": 0 } }, + { + "name": "t8", + "kind": { + "stream": null + }, + "owner": { + "interface": 0 + } + }, { "name": null, "kind": { @@ -173,7 +183,7 @@ "name": null, "kind": { "result": { - "ok": 15, + "ok": 16, "err": "string" } }, @@ -182,7 +192,7 @@ { "name": null, "kind": { - "future": 16 + "future": 17 }, "owner": null } @@ -196,4 +206,4 @@ "worlds": {} } ] -} \ No newline at end of file +}