diff --git a/libflux/flux-core/src/ast/mod.rs b/libflux/flux-core/src/ast/mod.rs index 76c048a13b..471092701e 100644 --- a/libflux/flux-core/src/ast/mod.rs +++ b/libflux/flux-core/src/ast/mod.rs @@ -609,6 +609,8 @@ pub enum MonoType { Record(RecordType), #[serde(rename = "FunctionType")] Function(Box), + #[serde(rename = "LabelType")] + Label(Box), } impl MonoType { @@ -622,6 +624,7 @@ impl MonoType { MonoType::Dict(t) => &t.base, MonoType::Record(t) => &t.base, MonoType::Function(t) => &t.base, + MonoType::Label(t) => &t.base, } } } diff --git a/libflux/flux-core/src/ast/walk/mod.rs b/libflux/flux-core/src/ast/walk/mod.rs index a55108e492..a4571e99a2 100644 --- a/libflux/flux-core/src/ast/walk/mod.rs +++ b/libflux/flux-core/src/ast/walk/mod.rs @@ -461,6 +461,7 @@ where walk(v, Node::MonoType(&f.monotype)); } + MonoType::Label(lit) => walk(v, Node::StringLit(lit)), }, Node::PropertyType(n) => { walk(v, Node::from_property_key(&n.name)); diff --git a/libflux/flux-core/src/formatter/mod.rs b/libflux/flux-core/src/formatter/mod.rs index e95535c5aa..9cc7ffdd46 100644 --- a/libflux/flux-core/src/formatter/mod.rs +++ b/libflux/flux-core/src/formatter/mod.rs @@ -488,6 +488,7 @@ impl<'doc> Formatter<'doc> { self.format_monotype(&n.monotype), ] } + ast::MonoType::Label(label) => self.format_string_literal(label), } .group() } diff --git a/libflux/flux-core/src/parser/mod.rs b/libflux/flux-core/src/parser/mod.rs index 0761c21f38..a28108f3c7 100644 --- a/libflux/flux-core/src/parser/mod.rs +++ b/libflux/flux-core/src/parser/mod.rs @@ -572,6 +572,7 @@ impl<'input> Parser<'input> { element: ty, })) } + TokenType::String => MonoType::Label(Box::new(self.parse_string_literal())), _ => { if t.lit.len() == 1 { self.parse_tvar() diff --git a/libflux/flux-core/src/semantic/bootstrap.rs b/libflux/flux-core/src/semantic/bootstrap.rs index 2565ac6f68..d7d44b20ab 100644 --- a/libflux/flux-core/src/semantic/bootstrap.rs +++ b/libflux/flux-core/src/semantic/bootstrap.rs @@ -23,7 +23,7 @@ use crate::{ types::{ MonoType, PolyType, PolyTypeHashMap, Record, RecordLabel, SemanticMap, Tvar, TvarKinds, }, - Analyzer, PackageExports, + Analyzer, AnalyzerConfig, PackageExports, }, }; @@ -43,10 +43,16 @@ pub type SemanticPackageMap = SemanticMap; /// Infers the Flux standard library given the path to the source code. /// The prelude and the imports are returned. #[allow(clippy::type_complexity)] -pub fn infer_stdlib_dir(path: &Path) -> Result<(PackageExports, Packages, SemanticPackageMap)> { +pub fn infer_stdlib_dir( + path: &Path, + config: AnalyzerConfig, +) -> Result<(PackageExports, Packages, SemanticPackageMap)> { let ast_packages = parse_dir(path)?; - let mut infer_state = InferState::default(); + let mut infer_state = InferState { + config, + ..InferState::default() + }; let prelude = infer_state.infer_pre(&ast_packages)?; infer_state.infer_std(&ast_packages, &prelude)?; @@ -75,13 +81,15 @@ pub fn parse_dir(dir: &Path) -> io::Result { // to work with either separator. normalized_path = normalized_path.replace('\\', "/"); } - files.push(parser::parse_string( + let source = fs::read_to_string(entry.path())?; + let ast = parser::parse_string( normalized_path .rsplitn(2, "/stdlib/") .collect::>()[0] .to_owned(), - &fs::read_to_string(entry.path())?, - )); + &source, + ); + files.push((source, ast)); } } } @@ -89,15 +97,19 @@ pub fn parse_dir(dir: &Path) -> io::Result { } // Associates an import path with each file -fn ast_map(files: Vec) -> ASTPackageMap { +fn ast_map(files: Vec<(String, ast::File)>) -> ASTPackageMap { files .into_iter() - .fold(ASTPackageMap::new(), |mut acc, file| { + .fold(ASTPackageMap::new(), |mut acc, (source, file)| { let path = file.name.rsplitn(2, '/').collect::>()[1].to_string(); acc.insert( path.clone(), ast::Package { base: ast::BaseNode { + location: ast::SourceLocation { + source: Some(source), + ..ast::SourceLocation::default() + }, ..ast::BaseNode::default() }, path, @@ -154,6 +166,7 @@ struct InferState { // types available for import imports: Packages, sem_pkg_map: SemanticPackageMap, + config: AnalyzerConfig, } impl InferState { @@ -241,8 +254,13 @@ impl InferState { .ok_or_else(|| anyhow!(r#"package import "{}" not found"#, name))?; let env = Environment::new(prelude.into()); - let mut analyzer = Analyzer::new_with_defaults(env, &mut self.imports); - let (exports, sem_pkg) = analyzer.analyze_ast(file).map_err(|err| err.error)?; + let mut analyzer = Analyzer::new(env, &mut self.imports, self.config.clone()); + let (exports, sem_pkg) = analyzer.analyze_ast(file).map_err(|mut err| { + if err.error.source.is_none() { + err.error.source = file.base.location.source.clone(); + } + err.error.pretty_error() + })?; Ok((exports, sem_pkg)) } @@ -342,7 +360,7 @@ pub fn stdlib(dir: &Path) -> Result<(PackageExports, FileSystemImporter)> /// Compiles the stdlib found at the srcdir into the outdir. pub fn compile_stdlib(srcdir: &Path, outdir: &Path) -> Result<()> { - let (_, imports, mut sem_pkgs) = infer_stdlib_dir(srcdir)?; + let (_, imports, mut sem_pkgs) = infer_stdlib_dir(srcdir, AnalyzerConfig::default())?; // Write each file as compiled module for (path, exports) in &imports { if let Some(code) = sem_pkgs.remove(path) { diff --git a/libflux/flux-core/src/semantic/convert.rs b/libflux/flux-core/src/semantic/convert.rs index e205d85070..bd2540cb0e 100644 --- a/libflux/flux-core/src/semantic/convert.rs +++ b/libflux/flux-core/src/semantic/convert.rs @@ -616,6 +616,10 @@ impl<'a> Converter<'a> { } r } + + ast::MonoType::Label(string_lit) => { + MonoType::Label(types::Label::from(string_lit.value.as_str())) + } } } diff --git a/libflux/flux-core/src/semantic/mod.rs b/libflux/flux-core/src/semantic/mod.rs index bfabf0d1d7..4728038446 100644 --- a/libflux/flux-core/src/semantic/mod.rs +++ b/libflux/flux-core/src/semantic/mod.rs @@ -270,6 +270,19 @@ fn build_record( (r, cons) } +/// Wrapper around `FileErrors` which defaults to using codespan to print the errors +#[derive(Error, Debug, PartialEq)] +pub struct PrettyFileErrors(pub FileErrors); + +impl fmt::Display for PrettyFileErrors { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match &self.0.source { + Some(source) => f.write_str(&self.0.pretty(source)), + None => self.0.fmt(f), + } + } +} + /// Error represents any any error that can occur during any step of the type analysis process. #[derive(Error, Debug, PartialEq)] pub struct FileErrors { @@ -320,6 +333,12 @@ impl FileErrors { self.pretty_config(&term::Config::default(), source) } + /// Wraps `FileErrors` in type which defaults to the more readable codespan error + /// representation + pub fn pretty_error(self) -> PrettyFileErrors { + PrettyFileErrors(self) + } + /// Prints the errors in their short form pub fn pretty_short(&self, source: &str) -> String { self.pretty_config( @@ -417,7 +436,7 @@ pub enum Feature { } /// A set of configuration options for the behavior of an Analyzer. -#[derive(Default)] +#[derive(Clone, Default, Debug)] pub struct AnalyzerConfig { /// Features used in the flux compiler pub features: Vec, diff --git a/libflux/flux-core/src/semantic/nodes.rs b/libflux/flux-core/src/semantic/nodes.rs index 09953cb690..011316830d 100644 --- a/libflux/flux-core/src/semantic/nodes.rs +++ b/libflux/flux-core/src/semantic/nodes.rs @@ -409,7 +409,6 @@ impl Substituter for FinalizeTypes<'_> { let typ = self.sub.try_apply(*tvr)?; Some(self.visit_type(&typ).unwrap_or(typ)) } - MonoType::Label(_) => Some(MonoType::STRING), _ => typ.walk(self), } } @@ -817,14 +816,10 @@ impl ArrayExpr { for el in &mut self.elements { el.infer(infer)?; - match &elt { - None => { - elt = Some(el.type_of()); - } - Some(elt) => { - infer.equal(elt, &el.type_of(), el.loc()); - } - } + elt = Some(match &elt { + None => el.type_of(), + Some(elt) => infer.equal(elt, &el.type_of(), el.loc()), + }); } let elt = elt.unwrap_or_else(|| MonoType::Var(infer.sub.fresh())); self.typ = MonoType::arr(elt); diff --git a/libflux/flux-core/src/semantic/tests/labels.rs b/libflux/flux-core/src/semantic/tests/labels.rs index 22f95416c9..79bdda038d 100644 --- a/libflux/flux-core/src/semantic/tests/labels.rs +++ b/libflux/flux-core/src/semantic/tests/labels.rs @@ -21,7 +21,7 @@ fn labels_simple() { z = [{ a: 1, b: ""}] |> fill(column: b, value: 1.0) "#, exp: map![ - "b" => "string", + "b" => "\"b\"", "x" => "[{ a: string }]", "y" => "[{ a: int, b: float }]", "z" => "[{ a: int, b: float }]", @@ -230,6 +230,25 @@ fn optional_label_defined() { } } +#[test] +fn label_types_are_preserved_in_exports() { + test_infer! { + config: AnalyzerConfig{ + features: vec![Feature::LabelPolymorphism], + ..AnalyzerConfig::default() + }, + src: r#" + builtin elapsed: (?timeColumn: T = "_time") => stream[{ A with T: time }] + where + A: Record, + T: Label + "#, + exp: map![ + "elapsed" => r#"(?timeColumn:A = "_time") => stream[{B with A:time}] where A: Label, B: Record"# + ], + } +} + #[test] fn optional_label_undefined() { test_error_msg! { diff --git a/libflux/flux-core/src/semantic/tests/vectorize.rs b/libflux/flux-core/src/semantic/tests/vectorize.rs index 8951d41eaf..020268a80b 100644 --- a/libflux/flux-core/src/semantic/tests/vectorize.rs +++ b/libflux/flux-core/src/semantic/tests/vectorize.rs @@ -50,8 +50,8 @@ fn vectorize_field_access() -> anyhow::Result<()> { expect_test::expect![[r##" (r) => { - return {a: r:{F with b:v[#B], a:v[#D]}.a:v[#D], b: r:{F with b:v[#B], a:v[#D]}.b:v[#B]}:{a:v[#D], b:v[#B]} - }:(r:{F with b:v[#B], a:v[#D]}) => {a:v[#D], b:v[#B]}"##]].assert_eq(&crate::semantic::formatter::format_node( + return {a: r:{#F with b:v[#B], a:v[#D]}.a:v[#D], b: r:{#F with b:v[#B], a:v[#D]}.b:v[#B]}:{a:v[#D], b:v[#B]} + }:(r:{#F with b:v[#B], a:v[#D]}) => {a:v[#D], b:v[#B]}"##]].assert_eq(&crate::semantic::formatter::format_node( Node::FunctionExpr(function), )?); @@ -66,8 +66,8 @@ fn vectorize_with_construction() -> anyhow::Result<()> { expect_test::expect![[r##" (r) => { - return {r:{C with a:v[#B]} with b: r:{C with a:v[#B]}.a:v[#B]}:{C with b:v[#B], a:v[#B]} - }:(r:{C with a:v[#B]}) => {C with b:v[#B], a:v[#B]}"##]] + return {r:{#C with a:v[#B]} with b: r:{#C with a:v[#B]}.a:v[#B]}:{#C with b:v[#B], a:v[#B]} + }:(r:{#C with a:v[#B]}) => {#C with b:v[#B], a:v[#B]}"##]] .assert_eq(&crate::semantic::formatter::format_node( Node::FunctionExpr(function), )?); @@ -88,8 +88,8 @@ fn vectorize_even_when_another_function_fails_to_vectorize() -> anyhow::Result<( expect_test::expect![[r##" (r) => { - return {r:{I with a:v[#G], b:v[#G]} with x: r:{I with a:v[#G], b:v[#G]}.a:v[#G] +:v[#G] r:{I with a:v[#G], b:v[#G]}.b:v[#G]}:{I with x:v[#G], a:v[#G], b:v[#G]} - }:(r:{I with a:v[#G], b:v[#G]}) => {I with x:v[#G], a:v[#G], b:v[#G]}"##]] + return {r:{#I with a:v[#G], b:v[#G]} with x: r:{#I with a:v[#G], b:v[#G]}.a:v[#G] +:v[#G] r:{#I with a:v[#G], b:v[#G]}.b:v[#G]}:{#I with x:v[#G], a:v[#G], b:v[#G]} + }:(r:{#I with a:v[#G], b:v[#G]}) => {#I with x:v[#G], a:v[#G], b:v[#G]}"##]] .assert_eq(&crate::semantic::formatter::format_node( Node::FunctionExpr(function), )?); @@ -117,8 +117,8 @@ fn vectorize_addition_operator() -> anyhow::Result<()> { expect_test::expect![[r##" (r) => { - return {x: r:{F with a:v[#D], b:v[#D]}.a:v[#D] +:v[#D] r:{F with a:v[#D], b:v[#D]}.b:v[#D]}:{x:v[#D]} - }:(r:{F with a:v[#D], b:v[#D]}) => {x:v[#D]}"##]].assert_eq(&crate::semantic::formatter::format_node( + return {x: r:{#F with a:v[#D], b:v[#D]}.a:v[#D] +:v[#D] r:{#F with a:v[#D], b:v[#D]}.b:v[#D]}:{x:v[#D]} + }:(r:{#F with a:v[#D], b:v[#D]}) => {x:v[#D]}"##]].assert_eq(&crate::semantic::formatter::format_node( Node::FunctionExpr(function), )?); @@ -133,8 +133,8 @@ fn vectorize_subtraction_operator() -> anyhow::Result<()> { expect_test::expect![[r##" (r) => { - return {x: r:{F with a:v[#D], b:v[#D]}.a:v[#D] -:v[#D] r:{F with a:v[#D], b:v[#D]}.b:v[#D]}:{x:v[#D]} - }:(r:{F with a:v[#D], b:v[#D]}) => {x:v[#D]}"##]].assert_eq(&crate::semantic::formatter::format_node( + return {x: r:{#F with a:v[#D], b:v[#D]}.a:v[#D] -:v[#D] r:{#F with a:v[#D], b:v[#D]}.b:v[#D]}:{x:v[#D]} + }:(r:{#F with a:v[#D], b:v[#D]}) => {x:v[#D]}"##]].assert_eq(&crate::semantic::formatter::format_node( Node::FunctionExpr(function), )?); diff --git a/libflux/flux-core/src/semantic/types.rs b/libflux/flux-core/src/semantic/types.rs index cf36423d55..fd19b79728 100644 --- a/libflux/flux-core/src/semantic/types.rs +++ b/libflux/flux-core/src/semantic/types.rs @@ -110,7 +110,7 @@ impl Matcher for Subsume { let expected = translate_label(unifier, expected, &actual); match (&*expected, &*actual) { // Labels should be accepted anywhere that we expect a string - (MonoType::Builtin(BuiltinType::String), MonoType::Label(_)) => MonoType::STRING, + (&MonoType::STRING, MonoType::Label(_)) => MonoType::STRING, _ => expected.unify_inner(&actual, unifier), } } @@ -539,7 +539,7 @@ where /// An ordered map of string identifiers to monotypes. /// Represents a Flux primitive primitive type such as int or string. -#[derive(Debug, Display, Clone, Copy, PartialEq, Serialize)] +#[derive(Debug, Display, Clone, Copy, Eq, PartialEq, Serialize)] #[allow(missing_docs)] pub enum BuiltinType { #[display(fmt = "bool")] @@ -564,7 +564,7 @@ pub enum BuiltinType { /// Represents a Flux type. The type may be unknown, represented as a type variable, /// or may be a known concrete type. -#[derive(Debug, Display, Clone, PartialEq)] +#[derive(Debug, Display, Clone, Eq, PartialEq)] #[allow(missing_docs)] pub enum MonoType { #[display(fmt = "")] @@ -653,7 +653,7 @@ impl Serialize for MonoType { } } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, Eq, PartialEq)] #[allow(missing_docs)] pub struct Collection { pub collection: CollectionType, @@ -676,7 +676,7 @@ impl fmt::Display for Collection { } } -#[derive(Debug, Clone, Copy, PartialEq)] +#[derive(Debug, Clone, Copy, Eq, PartialEq)] #[allow(missing_docs)] pub enum CollectionType { Array, @@ -1266,7 +1266,7 @@ impl Collection { } /// A key-value data structure. -#[derive(Debug, Display, Clone, PartialEq, Serialize)] +#[derive(Debug, Display, Clone, Eq, PartialEq, Serialize)] #[display(fmt = "[{}:{}]", key, val)] pub struct Dictionary { /// Type of key. @@ -1357,6 +1357,8 @@ fn collect_record(record: &Record) -> (RefMonoTypeVecMap<'_, RecordLabel>, Optio (a, fields.tail()) } +impl cmp::Eq for Record {} + impl cmp::PartialEq for Record { fn eq(&self, other: &Self) -> bool { let (a, t) = collect_record(self); @@ -1577,15 +1579,12 @@ impl Record { } } - fn format(&self, f: &mut String) -> Result, fmt::Error> { + fn format(&self, f: &mut String) -> Result, fmt::Error> { let mut fields = self.fields(); for head in &mut fields { write!(f, "{}, ", head)?; } - Ok(match fields.tail() { - Some(MonoType::BoundVar(tv)) | Some(MonoType::Var(tv)) => Some(*tv), - _ => None, - }) + Ok(fields.tail()) } /// Returns an iterator over the fields in the record @@ -1864,7 +1863,7 @@ impl Label { } /// A key-value pair representing a property type in a record. -#[derive(Debug, Display, Clone, PartialEq, Serialize)] +#[derive(Debug, Display, Clone, Eq, PartialEq, Serialize)] #[display(fmt = "{}:{}", k, v)] #[allow(missing_docs)] pub struct Property { @@ -1884,7 +1883,7 @@ where } /// Represents an (optional) argument to a function -#[derive(Debug, Clone, PartialEq, Serialize)] +#[derive(Debug, Clone, Eq, PartialEq, Serialize)] pub struct Argument { /// The default argument to the function (if one exists) pub default: Option, @@ -1926,7 +1925,7 @@ impl Argument { /// A function type is defined by a set of required arguments, /// a set of optional arguments, an optional pipe argument, and /// a required return type. -#[derive(Debug, Clone, PartialEq, Serialize)] +#[derive(Debug, Clone, Eq, PartialEq, Serialize)] pub struct Function { /// Required arguments to a function. pub req: MonoTypeMap, diff --git a/libflux/flux/benches/basic.rs b/libflux/flux/benches/basic.rs index 0a60703b1f..7e4927cbaf 100644 --- a/libflux/flux/benches/basic.rs +++ b/libflux/flux/benches/basic.rs @@ -27,7 +27,8 @@ fn everything(c: &mut Criterion) { let mut group = c.benchmark_group("infer"); group.sample_size(10).bench_function("bootstrap", |b| { b.iter(black_box(|| { - let (prelude, _, _) = bootstrap::infer_stdlib_dir(Path::new("../../stdlib")).unwrap(); + let (prelude, _, _) = + bootstrap::infer_stdlib_dir(Path::new("../../stdlib"), Default::default()).unwrap(); assert!(prelude.len() > 0); })); }); diff --git a/libflux/flux/build.rs b/libflux/flux/build.rs index 5cb7344a17..1636e20c9d 100644 --- a/libflux/flux/build.rs +++ b/libflux/flux/build.rs @@ -57,7 +57,8 @@ fn main() -> Result<()> { println!("cargo:rerun-if-changed={}", f); } - let (prelude, imports, sem_pkgs) = bootstrap::infer_stdlib_dir(stdlib_path)?; + let (prelude, imports, sem_pkgs) = + bootstrap::infer_stdlib_dir(stdlib_path, Default::default())?; // Validate there aren't any free type variables in the environment for (name, ty) in prelude.iter() { diff --git a/libflux/go/libflux/buildinfo.gen.go b/libflux/go/libflux/buildinfo.gen.go index 49e5dcd6fa..9ad0df5dcb 100644 --- a/libflux/go/libflux/buildinfo.gen.go +++ b/libflux/go/libflux/buildinfo.gen.go @@ -16,18 +16,18 @@ var sourceHashes = map[string]string{ "libflux/Cargo.toml": "91ac4e8b467440c6e8a9438011de0e7b78c2732403bb067d4dd31539ac8a90c1", "libflux/flux-core/Cargo.toml": "2290ce95d56e0f514b7c8285693a8011cddfc652bf2aad24edfeb43911f57ba9", "libflux/flux-core/src/ast/check/mod.rs": "47e06631f249715a44c9c8fa897faf142ad0fa26f67f8cfd5cd201e82cb1afc8", - "libflux/flux-core/src/ast/mod.rs": "9db1e55e75949ead038aacffd19d0a0cd32480c8fbab754727e60d07e94c58fa", - "libflux/flux-core/src/ast/walk/mod.rs": "133f5736c2cac7331019773f426af45bb4b3aa98bf71c26ac46ea96754b4efe4", + "libflux/flux-core/src/ast/mod.rs": "a410553122854cc383c75b06d553bc4b6a683e637962596ef946c52958b6a168", + "libflux/flux-core/src/ast/walk/mod.rs": "92dd40a0665f60ee1c1b0441580b3f2d3d57e75ea7f6d83fd5a73a759b10289d", "libflux/flux-core/src/bin/README.md": "c1245a4938c923d065647b4dc4f7e19486e85c93d868ef2f7f47ddff62ec81df", "libflux/flux-core/src/bin/fluxc.rs": "bf275289e690236988049fc0a07cf832dbac25bb5739c02135b069dcdfab4d0f", "libflux/flux-core/src/bin/fluxdoc.rs": "354a8dfd262f223412ee491a9947962f993e43c5467f8ee37c4f15528dc5b571", "libflux/flux-core/src/doc/example.rs": "6414756b3c74df1b58fdb739592e74ded3f89d85d647809333f72a3f6aad146f", "libflux/flux-core/src/doc/mod.rs": "e8aae31bc4a60836d7258a03f6827b76e9fad44c889db6a21d6679c26818f2d2", "libflux/flux-core/src/errors.rs": "b1d8a992686f20a41ea5996ac272625743b2770e3382f8113c4260f33cebf917", - "libflux/flux-core/src/formatter/mod.rs": "b9b129961fa284412c6d461af1742fd82f1090db066bf3dea3e921e917b9b8cd", + "libflux/flux-core/src/formatter/mod.rs": "5a90cfc05244b91ae4c326c4cf5aee4de8745d990ddf3c87d991c72f78bdc288", "libflux/flux-core/src/lib.rs": "443aed16dd600eecc1ffbee2d2dead6788e796cd5a278eb5dafb123843b8959e", "libflux/flux-core/src/map.rs": "342c1cc111d343f01b97f38be10a9f1097bdd57cdc56f55e92fd3ed5028e6973", - "libflux/flux-core/src/parser/mod.rs": "10065fa5bdadd85999e749060c08c8e9a44f673106a87e9f472036f6bb790660", + "libflux/flux-core/src/parser/mod.rs": "a2b043f5103ea487822f17c30e775e49d6bf3572684b13af677a9cfd1057cff6", "libflux/flux-core/src/parser/strconv.rs": "84d24110f8af4a40ff7584cb0a41e8a1f8949d19c1ec329719057c5302f7615d", "libflux/flux-core/src/scanner/mod.rs": "297809a7b5778363a490bc4e08add05005bdc50d7c8cd59f27390f6316aba69e", "libflux/flux-core/src/scanner/scanner.rl": "e3755aed899244461e8b2a05a87ab41a89fe3d66d28f60c25ad9895f26675ba8", @@ -35,9 +35,9 @@ var sourceHashes = map[string]string{ "libflux/flux-core/src/scanner/token.rs": "5090c2ac4b341566a85f7d9ed9b48746dd2084ec2f3effdb4a7dc16cf34d44b9", "libflux/flux-core/src/scanner/unicode.rl": "f923f3b385ddfa65c74427b11971785fc25ea806ca03d547045de808e16ef9a1", "libflux/flux-core/src/scanner/unicode.rl.COPYING": "6cf2d5d26d52772ded8a5f0813f49f83dfa76006c5f398713be3854fe7bc4c7e", - "libflux/flux-core/src/semantic/bootstrap.rs": "6452c943cf1092575478358255517384348c0473bddfa1d40c1237b5a95fa35c", + "libflux/flux-core/src/semantic/bootstrap.rs": "1fc8e72e74f7b08df75b6b9802fcc2e02e5b9d890da82b4877e109ea72cc02fb", "libflux/flux-core/src/semantic/check.rs": "d0228a0a8176a5360d88cfe48acb1ffd036817b6aaadfadb94af446492603305", - "libflux/flux-core/src/semantic/convert.rs": "43d6143f6a34515354548a89d673b9bb731399fb51c38be76f103d5dc3f77718", + "libflux/flux-core/src/semantic/convert.rs": "82aed0bf2a0d7cf24a3331f233ff945dc35a64b49449fec445117c4c70208b76", "libflux/flux-core/src/semantic/env.rs": "8da036aa5f0e09f94fd2461687e97131068e56c762bef8cd98cfd91f36ef3e98", "libflux/flux-core/src/semantic/flatbuffers/mod.rs": "270671ffdcb1eb5308f9bbab0431c9464df264070a2deb05c526d182a6ec5585", "libflux/flux-core/src/semantic/flatbuffers/semantic_generated.rs": "beaaa6b08d8b56dba81153a58e440bbdc430b4eca0201a3431e90b793f1adbce", @@ -47,10 +47,10 @@ var sourceHashes = map[string]string{ "libflux/flux-core/src/semantic/fs.rs": "f7f609bc8149769d99b737150e184a2d54029c0b768365dbcf08ff193b0e1f6f", "libflux/flux-core/src/semantic/import.rs": "184e955211db1ceb1be782b4daf75584b86907b1428e50015497909cfc2dd89a", "libflux/flux-core/src/semantic/infer.rs": "fcbe1bb017c3caf7935a1d29ec88b60b8f54defa047f6a915a8d941b2db154be", - "libflux/flux-core/src/semantic/mod.rs": "c751863e3544b392b82569bac094134b739a6d7fec944a1aa603c1491f4515d6", - "libflux/flux-core/src/semantic/nodes.rs": "e46dc4cebc642bc40e9cb1d325ebc9d68f147bf517307f0b310bf3379277716c", + "libflux/flux-core/src/semantic/mod.rs": "3cec76c645e411592898a3e153d571787157bdfdf8552c21748c5e8c5e41d48d", + "libflux/flux-core/src/semantic/nodes.rs": "ee3865bb9edf67dcc3baa8b74fcbd132a00f7eb2cf937d9f6bbcb3d3bccce454", "libflux/flux-core/src/semantic/sub.rs": "792b4a81d514e991d93998f407aa90527812c7c107ee827554b902b0af40aba3", - "libflux/flux-core/src/semantic/types.rs": "cddb5a921cf4d23afb2afcc99bb0c8309992f3b55748b7845266d6007f5976aa", + "libflux/flux-core/src/semantic/types.rs": "bd49bcf2da204a4e68a8612df68c499a4eaf65988a424a12bd71f5be4dd1be6f", "libflux/flux-core/src/semantic/vectorize.rs": "6ce2dc4e6ff572abc0146a220291322ea88557ce674ae16220a2d67420e9fa0d", "libflux/flux-core/src/semantic/walk/_walk.rs": "198e6c546f73f78b1de4b963084033a06a6d71e72b0294b16c5e4de874f97a38", "libflux/flux-core/src/semantic/walk/mod.rs": "a0eab3f225dc294569217da295d44f31073e643073e6b00fec5846cde2382ade", @@ -58,7 +58,7 @@ var sourceHashes = map[string]string{ "libflux/flux-core/src/semantic/walk/walk_mut.rs": "4dff7aaf3c1904da9ce955aaa33b24c74de41084fee3942eb9b8e960ec448250", "libflux/flux/Cargo.toml": "9fae0ee886a5c5278ad6b4606c36d9e929ab9529995856a333a618caae35c210", "libflux/flux/FLUXDOC.md": "92e6dd8043bd87b4924e09aa28fb5346630aee1214de28ea2c8fc0687cad0785", - "libflux/flux/build.rs": "715ad64aacaa8bd91e5432b9487539706b272026a609f629038ccb07ee060618", + "libflux/flux/build.rs": "6f2a4da51744a174ab13a1ebcb18ea39c0acfc2c720e7a61ea3e326fb0649529", "libflux/flux/src/cffi.rs": "598412e4d6faa5aa7858dad228b09999c89f2f46f42b5a062a2202be3e5676e1", "libflux/flux/src/lib.rs": "3cd7dfcf7491f5797d501a647ee92a3f66b5790f6df7ed2238f1969b4bd929ed", "libflux/flux/templates/base.html": "a818747b9621828bb96b94291c60922db54052bbe35d5e354f8e589d2a4ebd02",