add support for incomplete_wire -- a wire that you can supply the type of later
This commit is contained in:
parent
ff94dda922
commit
df55a514e4
|
@ -65,6 +65,7 @@ mod kw {
|
||||||
custom_keyword!(hdl);
|
custom_keyword!(hdl);
|
||||||
custom_keyword!(hdl_module);
|
custom_keyword!(hdl_module);
|
||||||
custom_keyword!(input);
|
custom_keyword!(input);
|
||||||
|
custom_keyword!(incomplete_wire);
|
||||||
custom_keyword!(instance);
|
custom_keyword!(instance);
|
||||||
custom_keyword!(m);
|
custom_keyword!(m);
|
||||||
custom_keyword!(memory);
|
custom_keyword!(memory);
|
||||||
|
|
|
@ -34,6 +34,7 @@ options! {
|
||||||
Instance(instance),
|
Instance(instance),
|
||||||
RegBuilder(reg_builder),
|
RegBuilder(reg_builder),
|
||||||
Wire(wire),
|
Wire(wire),
|
||||||
|
IncompleteWire(incomplete_wire),
|
||||||
Memory(memory),
|
Memory(memory),
|
||||||
MemoryArray(memory_array),
|
MemoryArray(memory_array),
|
||||||
MemoryWithInit(memory_with_init),
|
MemoryWithInit(memory_with_init),
|
||||||
|
@ -533,6 +534,41 @@ impl HdlLetKindToTokens for HdlLetKindWire {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
options! {
|
||||||
|
pub(crate) enum LetFnKindIncomplete {
|
||||||
|
IncompleteWire(incomplete_wire),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub(crate) struct HdlLetKindIncomplete {
|
||||||
|
pub(crate) kind: LetFnKindIncomplete,
|
||||||
|
pub(crate) paren: Paren,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ParseTypes<Self> for HdlLetKindIncomplete {
|
||||||
|
fn parse_types(input: &mut Self, _parser: &mut TypesParser<'_>) -> Result<Self, ParseFailed> {
|
||||||
|
Ok(input.clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl_fold! {
|
||||||
|
struct HdlLetKindIncomplete<> {
|
||||||
|
kind: LetFnKindIncomplete,
|
||||||
|
paren: Paren,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HdlLetKindToTokens for HdlLetKindIncomplete {
|
||||||
|
fn ty_to_tokens(&self, _tokens: &mut TokenStream) {}
|
||||||
|
|
||||||
|
fn expr_to_tokens(&self, tokens: &mut TokenStream) {
|
||||||
|
let Self { kind, paren } = self;
|
||||||
|
kind.to_tokens(tokens);
|
||||||
|
paren.surround(tokens, |_| {});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
options! {
|
options! {
|
||||||
pub(crate) enum MemoryFnName {
|
pub(crate) enum MemoryFnName {
|
||||||
Memory(memory),
|
Memory(memory),
|
||||||
|
@ -697,6 +733,7 @@ impl HdlLetKindMemory {
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub(crate) enum HdlLetKind<IOType = ParsedType> {
|
pub(crate) enum HdlLetKind<IOType = ParsedType> {
|
||||||
IO(HdlLetKindIO<ModuleIOKind, IOType>),
|
IO(HdlLetKindIO<ModuleIOKind, IOType>),
|
||||||
|
Incomplete(HdlLetKindIncomplete),
|
||||||
Instance(HdlLetKindInstance),
|
Instance(HdlLetKindInstance),
|
||||||
RegBuilder(HdlLetKindRegBuilder),
|
RegBuilder(HdlLetKindRegBuilder),
|
||||||
Wire(HdlLetKindWire),
|
Wire(HdlLetKindWire),
|
||||||
|
@ -706,6 +743,7 @@ pub(crate) enum HdlLetKind<IOType = ParsedType> {
|
||||||
impl_fold! {
|
impl_fold! {
|
||||||
enum HdlLetKind<IOType,> {
|
enum HdlLetKind<IOType,> {
|
||||||
IO(HdlLetKindIO<ModuleIOKind, IOType>),
|
IO(HdlLetKindIO<ModuleIOKind, IOType>),
|
||||||
|
Incomplete(HdlLetKindIncomplete),
|
||||||
Instance(HdlLetKindInstance),
|
Instance(HdlLetKindInstance),
|
||||||
RegBuilder(HdlLetKindRegBuilder),
|
RegBuilder(HdlLetKindRegBuilder),
|
||||||
Wire(HdlLetKindWire),
|
Wire(HdlLetKindWire),
|
||||||
|
@ -720,6 +758,9 @@ impl<T: ParseTypes<I>, I> ParseTypes<HdlLetKind<I>> for HdlLetKind<T> {
|
||||||
) -> Result<Self, ParseFailed> {
|
) -> Result<Self, ParseFailed> {
|
||||||
match input {
|
match input {
|
||||||
HdlLetKind::IO(input) => ParseTypes::parse_types(input, parser).map(HdlLetKind::IO),
|
HdlLetKind::IO(input) => ParseTypes::parse_types(input, parser).map(HdlLetKind::IO),
|
||||||
|
HdlLetKind::Incomplete(input) => {
|
||||||
|
ParseTypes::parse_types(input, parser).map(HdlLetKind::Incomplete)
|
||||||
|
}
|
||||||
HdlLetKind::Instance(input) => {
|
HdlLetKind::Instance(input) => {
|
||||||
ParseTypes::parse_types(input, parser).map(HdlLetKind::Instance)
|
ParseTypes::parse_types(input, parser).map(HdlLetKind::Instance)
|
||||||
}
|
}
|
||||||
|
@ -871,6 +912,20 @@ impl HdlLetKindParse for HdlLetKind<Type> {
|
||||||
ty_expr: paren_contents.call(parse_optional_fn_arg)?,
|
ty_expr: paren_contents.call(parse_optional_fn_arg)?,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
LetFnKind::IncompleteWire(incomplete_wire) => {
|
||||||
|
if let Some(parsed_ty) = parsed_ty {
|
||||||
|
return Err(Error::new_spanned(
|
||||||
|
parsed_ty.1,
|
||||||
|
"type annotation not allowed for incomplete_wire",
|
||||||
|
));
|
||||||
|
}
|
||||||
|
check_empty_m_dot(m_dot, kind)?;
|
||||||
|
let _paren_contents;
|
||||||
|
Ok(Self::Incomplete(HdlLetKindIncomplete {
|
||||||
|
kind: LetFnKindIncomplete::IncompleteWire(incomplete_wire),
|
||||||
|
paren: parenthesized!(_paren_contents in input),
|
||||||
|
}))
|
||||||
|
}
|
||||||
LetFnKind::Memory(fn_name) => HdlLetKindMemory::rest_of_parse(
|
LetFnKind::Memory(fn_name) => HdlLetKindMemory::rest_of_parse(
|
||||||
input,
|
input,
|
||||||
parsed_ty,
|
parsed_ty,
|
||||||
|
@ -903,6 +958,7 @@ impl HdlLetKindToTokens for HdlLetKind {
|
||||||
fn ty_to_tokens(&self, tokens: &mut TokenStream) {
|
fn ty_to_tokens(&self, tokens: &mut TokenStream) {
|
||||||
match self {
|
match self {
|
||||||
HdlLetKind::IO(v) => v.ty_to_tokens(tokens),
|
HdlLetKind::IO(v) => v.ty_to_tokens(tokens),
|
||||||
|
HdlLetKind::Incomplete(v) => v.ty_to_tokens(tokens),
|
||||||
HdlLetKind::Instance(v) => v.ty_to_tokens(tokens),
|
HdlLetKind::Instance(v) => v.ty_to_tokens(tokens),
|
||||||
HdlLetKind::RegBuilder(v) => v.ty_to_tokens(tokens),
|
HdlLetKind::RegBuilder(v) => v.ty_to_tokens(tokens),
|
||||||
HdlLetKind::Wire(v) => v.ty_to_tokens(tokens),
|
HdlLetKind::Wire(v) => v.ty_to_tokens(tokens),
|
||||||
|
@ -913,6 +969,7 @@ impl HdlLetKindToTokens for HdlLetKind {
|
||||||
fn expr_to_tokens(&self, tokens: &mut TokenStream) {
|
fn expr_to_tokens(&self, tokens: &mut TokenStream) {
|
||||||
match self {
|
match self {
|
||||||
HdlLetKind::IO(v) => v.expr_to_tokens(tokens),
|
HdlLetKind::IO(v) => v.expr_to_tokens(tokens),
|
||||||
|
HdlLetKind::Incomplete(v) => v.expr_to_tokens(tokens),
|
||||||
HdlLetKind::Instance(v) => v.expr_to_tokens(tokens),
|
HdlLetKind::Instance(v) => v.expr_to_tokens(tokens),
|
||||||
HdlLetKind::RegBuilder(v) => v.expr_to_tokens(tokens),
|
HdlLetKind::RegBuilder(v) => v.expr_to_tokens(tokens),
|
||||||
HdlLetKind::Wire(v) => v.expr_to_tokens(tokens),
|
HdlLetKind::Wire(v) => v.expr_to_tokens(tokens),
|
||||||
|
@ -1369,6 +1426,31 @@ impl Visitor<'_> {
|
||||||
semi_token: hdl_let.semi_token,
|
semi_token: hdl_let.semi_token,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fn process_hdl_let_incomplete(&mut self, hdl_let: HdlLet<HdlLetKindIncomplete>) -> Local {
|
||||||
|
let name = &hdl_let.name;
|
||||||
|
let kind = hdl_let.kind.kind;
|
||||||
|
self.require_normal_module_or_fn(kind);
|
||||||
|
let mut expr = kind.to_token_stream();
|
||||||
|
hdl_let.kind.paren.surround(&mut expr, |expr| {
|
||||||
|
ImplicitName {
|
||||||
|
name,
|
||||||
|
span: name.span(),
|
||||||
|
}
|
||||||
|
.to_tokens(expr);
|
||||||
|
});
|
||||||
|
let mut_token = &hdl_let.mut_token;
|
||||||
|
Local {
|
||||||
|
attrs: hdl_let.attrs.clone(),
|
||||||
|
let_token: hdl_let.let_token,
|
||||||
|
pat: parse_quote! { #mut_token #name },
|
||||||
|
init: Some(LocalInit {
|
||||||
|
eq_token: hdl_let.eq_token,
|
||||||
|
expr: parse_quote! { #expr },
|
||||||
|
diverge: None,
|
||||||
|
}),
|
||||||
|
semi_token: hdl_let.semi_token,
|
||||||
|
}
|
||||||
|
}
|
||||||
fn process_hdl_let_memory(&mut self, hdl_let: HdlLet<HdlLetKindMemory>) -> Local {
|
fn process_hdl_let_memory(&mut self, hdl_let: HdlLet<HdlLetKindMemory>) -> Local {
|
||||||
let name = &hdl_let.name;
|
let name = &hdl_let.name;
|
||||||
let memory_fn = hdl_let.kind.memory_fn;
|
let memory_fn = hdl_let.kind.memory_fn;
|
||||||
|
@ -1438,6 +1520,7 @@ impl Visitor<'_> {
|
||||||
}
|
}
|
||||||
the_match! {
|
the_match! {
|
||||||
IO => process_hdl_let_io,
|
IO => process_hdl_let_io,
|
||||||
|
Incomplete => process_hdl_let_incomplete,
|
||||||
Instance => process_hdl_let_instance,
|
Instance => process_hdl_let_instance,
|
||||||
RegBuilder => process_hdl_let_reg_builder,
|
RegBuilder => process_hdl_let_reg_builder,
|
||||||
Wire => process_hdl_let_wire,
|
Wire => process_hdl_let_wire,
|
||||||
|
|
|
@ -22,7 +22,7 @@ use crate::{
|
||||||
source_location::SourceLocation,
|
source_location::SourceLocation,
|
||||||
ty::{CanonicalType, Type},
|
ty::{CanonicalType, Type},
|
||||||
util::ScopedRef,
|
util::ScopedRef,
|
||||||
wire::Wire,
|
wire::{IncompleteWire, Wire},
|
||||||
};
|
};
|
||||||
use hashbrown::{hash_map::Entry, HashMap, HashSet};
|
use hashbrown::{hash_map::Entry, HashMap, HashSet};
|
||||||
use num_bigint::BigInt;
|
use num_bigint::BigInt;
|
||||||
|
@ -118,9 +118,35 @@ pub trait BlockRef: 'static + Send + Sync + Copy + Eq + Hash + fmt::Debug {}
|
||||||
|
|
||||||
impl BlockRef for BlockId {}
|
impl BlockRef for BlockId {}
|
||||||
|
|
||||||
|
pub(crate) enum IncompleteDeclaration {
|
||||||
|
Incomplete {
|
||||||
|
name: ScopedNameId,
|
||||||
|
source_location: SourceLocation,
|
||||||
|
},
|
||||||
|
Complete(StmtDeclaration<ModuleBuilding>),
|
||||||
|
Taken,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Debug for IncompleteDeclaration {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
Self::Incomplete {
|
||||||
|
name,
|
||||||
|
source_location: _,
|
||||||
|
} => f
|
||||||
|
.debug_struct("Incomplete")
|
||||||
|
.field("name", name)
|
||||||
|
.finish_non_exhaustive(),
|
||||||
|
Self::Complete(v) => v.fmt(f),
|
||||||
|
Self::Taken => f.write_str("Taken"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct BuilderBlock {
|
pub struct BuilderBlock {
|
||||||
memories: Vec<Rc<RefCell<MemBuilderTarget>>>,
|
memories: Vec<Rc<RefCell<MemBuilderTarget>>>,
|
||||||
|
incomplete_declarations: Vec<Rc<RefCell<IncompleteDeclaration>>>,
|
||||||
stmts: Vec<Stmt<ModuleBuilding>>,
|
stmts: Vec<Stmt<ModuleBuilding>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -831,13 +857,34 @@ impl From<NormalModuleBody<ModuleBuilding>> for NormalModuleBody {
|
||||||
annotations_map: &mut HashMap<StmtDeclaration<ModuleBuilding>, Vec<TargetedAnnotation>>,
|
annotations_map: &mut HashMap<StmtDeclaration<ModuleBuilding>, Vec<TargetedAnnotation>>,
|
||||||
block_id: BlockId,
|
block_id: BlockId,
|
||||||
) -> Block {
|
) -> Block {
|
||||||
let BuilderBlock { memories, stmts } = &mut blocks[block_id.as_usize()];
|
let BuilderBlock {
|
||||||
|
memories,
|
||||||
|
incomplete_declarations,
|
||||||
|
stmts,
|
||||||
|
} = &mut blocks[block_id.as_usize()];
|
||||||
let memories = Interned::from_iter(
|
let memories = Interned::from_iter(
|
||||||
memories
|
memories
|
||||||
.drain(..)
|
.drain(..)
|
||||||
.filter_map(|memory| memory.borrow().make_memory()),
|
.filter_map(|memory| memory.borrow().make_memory()),
|
||||||
);
|
);
|
||||||
let stmts = std::mem::take(stmts);
|
let stmts = Vec::from_iter(
|
||||||
|
incomplete_declarations
|
||||||
|
.drain(..)
|
||||||
|
.map(|decl| {
|
||||||
|
match std::mem::replace(
|
||||||
|
&mut *decl.borrow_mut(),
|
||||||
|
IncompleteDeclaration::Taken,
|
||||||
|
) {
|
||||||
|
IncompleteDeclaration::Incomplete {
|
||||||
|
name,
|
||||||
|
source_location,
|
||||||
|
} => panic!("incomplete declaration: {name:?}\nat: {source_location}"),
|
||||||
|
IncompleteDeclaration::Complete(v) => Stmt::Declaration(v),
|
||||||
|
IncompleteDeclaration::Taken => unreachable!(),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.chain(stmts.drain(..)),
|
||||||
|
);
|
||||||
let stmts = Interned::from_iter(stmts.into_iter().map(|stmt| {
|
let stmts = Interned::from_iter(stmts.into_iter().map(|stmt| {
|
||||||
match stmt {
|
match stmt {
|
||||||
Stmt::Connect(stmt) => stmt.into(),
|
Stmt::Connect(stmt) => stmt.into(),
|
||||||
|
@ -908,6 +955,7 @@ impl NormalModuleBody<ModuleBuilding> {
|
||||||
let index = self.body.blocks.len();
|
let index = self.body.blocks.len();
|
||||||
self.body.blocks.push(BuilderBlock {
|
self.body.blocks.push(BuilderBlock {
|
||||||
memories: vec![],
|
memories: vec![],
|
||||||
|
incomplete_declarations: vec![],
|
||||||
stmts: vec![],
|
stmts: vec![],
|
||||||
});
|
});
|
||||||
BlockId(index)
|
BlockId(index)
|
||||||
|
@ -1943,6 +1991,7 @@ impl ModuleBuilder {
|
||||||
body: BuilderModuleBody {
|
body: BuilderModuleBody {
|
||||||
blocks: vec![BuilderBlock {
|
blocks: vec![BuilderBlock {
|
||||||
memories: vec![],
|
memories: vec![],
|
||||||
|
incomplete_declarations: vec![],
|
||||||
stmts: vec![],
|
stmts: vec![],
|
||||||
}],
|
}],
|
||||||
annotations_map: HashMap::new(),
|
annotations_map: HashMap::new(),
|
||||||
|
@ -2156,6 +2205,42 @@ pub fn wire<T: Type>(implicit_name: ImplicitName<'_>, ty: T) -> Expr<T> {
|
||||||
wire_with_loc(implicit_name.0, SourceLocation::caller(), ty)
|
wire_with_loc(implicit_name.0, SourceLocation::caller(), ty)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[track_caller]
|
||||||
|
fn incomplete_declaration(
|
||||||
|
name: &str,
|
||||||
|
source_location: SourceLocation,
|
||||||
|
) -> Rc<RefCell<IncompleteDeclaration>> {
|
||||||
|
ModuleBuilder::with(|m| {
|
||||||
|
let mut impl_ = m.impl_.borrow_mut();
|
||||||
|
let scoped_name = ScopedNameId(m.name, impl_.name_id_gen.gen(name.intern()));
|
||||||
|
drop(impl_);
|
||||||
|
let retval = Rc::new(RefCell::new(IncompleteDeclaration::Incomplete {
|
||||||
|
name: scoped_name,
|
||||||
|
source_location,
|
||||||
|
}));
|
||||||
|
let mut impl_ = m.impl_.borrow_mut();
|
||||||
|
impl_
|
||||||
|
.body
|
||||||
|
.builder_normal_body()
|
||||||
|
.block(m.block_stack.top())
|
||||||
|
.incomplete_declarations
|
||||||
|
.push(retval.clone());
|
||||||
|
retval
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[track_caller]
|
||||||
|
pub fn incomplete_wire_with_loc(name: &str, source_location: SourceLocation) -> IncompleteWire {
|
||||||
|
IncompleteWire {
|
||||||
|
declaration: incomplete_declaration(name, source_location),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[track_caller]
|
||||||
|
pub fn incomplete_wire(implicit_name: ImplicitName<'_>) -> IncompleteWire {
|
||||||
|
incomplete_wire_with_loc(implicit_name.0, SourceLocation::caller())
|
||||||
|
}
|
||||||
|
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
pub fn reg_builder_with_loc(name: &str, source_location: SourceLocation) -> RegBuilder<(), (), ()> {
|
pub fn reg_builder_with_loc(name: &str, source_location: SourceLocation) -> RegBuilder<(), (), ()> {
|
||||||
ModuleBuilder::with(|m| {
|
ModuleBuilder::with(|m| {
|
||||||
|
|
|
@ -9,8 +9,8 @@ pub use crate::{
|
||||||
int::{Bool, DynSize, IntCmp, KnownSize, SInt, SIntType, Size, UInt, UIntType},
|
int::{Bool, DynSize, IntCmp, KnownSize, SInt, SIntType, Size, UInt, UIntType},
|
||||||
memory::{Mem, MemBuilder, ReadUnderWrite},
|
memory::{Mem, MemBuilder, ReadUnderWrite},
|
||||||
module::{
|
module::{
|
||||||
annotate, connect, connect_any, instance, memory, memory_array, memory_with_init,
|
annotate, connect, connect_any, incomplete_wire, instance, memory, memory_array,
|
||||||
reg_builder, wire, Instance, Module, ModuleBuilder,
|
memory_with_init, reg_builder, wire, Instance, Module, ModuleBuilder,
|
||||||
},
|
},
|
||||||
reg::Reg,
|
reg::Reg,
|
||||||
reset::{AsyncReset, Reset, SyncReset, ToAsyncReset, ToReset, ToSyncReset},
|
reset::{AsyncReset, Reset, SyncReset, ToAsyncReset, ToReset, ToSyncReset},
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||||
// See Notices.txt for copyright information
|
// See Notices.txt for copyright information
|
||||||
use crate::{
|
use crate::{
|
||||||
expr::Flow,
|
expr::{Expr, Flow, ToExpr},
|
||||||
intern::Interned,
|
intern::Interned,
|
||||||
module::{NameId, ScopedNameId},
|
module::{IncompleteDeclaration, NameId, ScopedNameId, StmtDeclaration, StmtWire},
|
||||||
source_location::SourceLocation,
|
source_location::SourceLocation,
|
||||||
ty::{CanonicalType, Type},
|
ty::{CanonicalType, Type},
|
||||||
};
|
};
|
||||||
use std::fmt;
|
use std::{cell::RefCell, fmt, rc::Rc};
|
||||||
|
|
||||||
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
|
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
|
||||||
pub struct Wire<T: Type> {
|
pub struct Wire<T: Type> {
|
||||||
|
@ -76,3 +76,57 @@ impl<T: Type> Wire<T> {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct IncompleteWire {
|
||||||
|
pub(crate) declaration: Rc<RefCell<IncompleteDeclaration>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IncompleteWire {
|
||||||
|
#[track_caller]
|
||||||
|
pub fn complete<T: Type>(&mut self, ty: T) -> Expr<T> {
|
||||||
|
let canonical_type = ty.canonical();
|
||||||
|
let mut declaration = self.declaration.borrow_mut();
|
||||||
|
if let IncompleteDeclaration::Incomplete {
|
||||||
|
name,
|
||||||
|
source_location,
|
||||||
|
} = *declaration
|
||||||
|
{
|
||||||
|
*declaration = IncompleteDeclaration::Complete(
|
||||||
|
StmtWire {
|
||||||
|
annotations: (),
|
||||||
|
wire: Wire {
|
||||||
|
name,
|
||||||
|
source_location,
|
||||||
|
ty: canonical_type,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
match *declaration {
|
||||||
|
IncompleteDeclaration::Complete(StmtDeclaration::Wire(StmtWire {
|
||||||
|
wire:
|
||||||
|
Wire {
|
||||||
|
name,
|
||||||
|
source_location,
|
||||||
|
ty: wire_ty,
|
||||||
|
},
|
||||||
|
..
|
||||||
|
})) => {
|
||||||
|
drop(declaration);
|
||||||
|
assert_eq!(wire_ty, canonical_type, "type mismatch");
|
||||||
|
Wire {
|
||||||
|
name,
|
||||||
|
source_location,
|
||||||
|
ty,
|
||||||
|
}
|
||||||
|
.to_expr()
|
||||||
|
}
|
||||||
|
IncompleteDeclaration::Taken => panic!("can't use wire outside of containing module"),
|
||||||
|
IncompleteDeclaration::Complete(_) | IncompleteDeclaration::Incomplete { .. } => {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue