diff --git a/Cargo.lock b/Cargo.lock index 68ed66bba..6798c1a05 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1218,6 +1218,7 @@ dependencies = [ "ena", "fe-common2", "fe-compiler-test-utils", + "fe-driver2", "fe-hir", "if_chain", "itertools", diff --git a/crates/driver2/src/diagnostics.rs b/crates/driver2/src/diagnostics.rs index 896141c60..b0b633749 100644 --- a/crates/driver2/src/diagnostics.rs +++ b/crates/driver2/src/diagnostics.rs @@ -7,19 +7,22 @@ use common::{ InputDb, InputFile, }; use cs::{diagnostic as cs_diag, files as cs_files}; -use hir::diagnostics::DiagnosticVoucher; +use hir::{diagnostics::DiagnosticVoucher, SpannedHirDb}; -use crate::{DriverDataBase, DriverDb}; +use crate::DriverDb; pub trait ToCsDiag { - fn to_cs(&self, db: &dyn DriverDb) -> cs_diag::Diagnostic; + fn to_cs(&self, db: &dyn SpannedInputDb) -> cs_diag::Diagnostic; } +pub trait SpannedInputDb: SpannedHirDb + InputDb {} +impl SpannedInputDb for T where T: SpannedHirDb + InputDb {} + impl ToCsDiag for T where T: for<'db> DiagnosticVoucher<'db>, { - fn to_cs(&self, db: &dyn DriverDb) -> cs_diag::Diagnostic { + fn to_cs(&self, db: &dyn SpannedInputDb) -> cs_diag::Diagnostic { let complete = self.to_complete(db.as_spanned_hir_db()); let severity = convert_severity(complete.severity); @@ -67,17 +70,19 @@ pub fn file_line_starts(db: &dyn DriverDb, file: InputFile) -> Vec { cs::files::line_starts(file.text(db.as_input_db())).collect() } -impl<'db> cs_files::Files<'db> for DriverDataBase { +pub struct CsDbWrapper<'a>(pub &'a dyn DriverDb); + +impl<'db> cs_files::Files<'db> for CsDbWrapper<'db> { type FileId = InputFile; type Name = &'db Utf8Path; type Source = &'db str; fn name(&'db self, file_id: Self::FileId) -> Result { - Ok(file_id.path(self.as_input_db()).as_path()) + Ok(file_id.path(self.0.as_input_db()).as_path()) } fn source(&'db self, file_id: Self::FileId) -> Result { - Ok(file_id.text(self.as_input_db())) + Ok(file_id.text(self.0.as_input_db())) } fn line_index( @@ -85,7 +90,7 @@ impl<'db> cs_files::Files<'db> for DriverDataBase { file_id: Self::FileId, byte_index: usize, ) -> Result { - let starts = file_line_starts(self, file_id); + let starts = file_line_starts(self.0, file_id); Ok(starts .binary_search(&byte_index) .unwrap_or_else(|next_line| next_line - 1)) @@ -96,7 +101,7 @@ impl<'db> cs_files::Files<'db> for DriverDataBase { file_id: Self::FileId, line_index: usize, ) -> Result, cs_files::Error> { - let line_starts = file_line_starts(self, file_id); + let line_starts = file_line_starts(self.0, file_id); let start = *line_starts .get(line_index) @@ -106,7 +111,7 @@ impl<'db> cs_files::Files<'db> for DriverDataBase { })?; let end = if line_index == line_starts.len() - 1 { - file_id.text(self.as_input_db()).len() + file_id.text(self.0.as_input_db()).len() } else { *line_starts .get(line_index + 1) diff --git a/crates/driver2/src/lib.rs b/crates/driver2/src/lib.rs index e00852638..19b0aca08 100644 --- a/crates/driver2/src/lib.rs +++ b/crates/driver2/src/lib.rs @@ -12,6 +12,7 @@ use common::{ input::{IngotKind, Version}, InputDb, InputFile, InputIngot, }; +pub use diagnostics::CsDbWrapper; use hir::{ analysis_pass::AnalysisPassManager, diagnostics::DiagnosticVoucher, hir_def::TopLevelMod, lower::map_file_to_mod, HirDb, LowerHirDb, ParsingPass, SpannedHirDb, @@ -109,7 +110,7 @@ impl<'db> DiagnosticsCollection<'db> { let config = term::Config::default(); for diag in self.finalize(db) { - term::emit(&mut buffer, &config, db, &diag.to_cs(db)).unwrap(); + term::emit(&mut buffer, &config, &CsDbWrapper(db), &diag.to_cs(db)).unwrap(); } eprintln!("{}", std::str::from_utf8(buffer.as_slice()).unwrap()); @@ -122,7 +123,7 @@ impl<'db> DiagnosticsCollection<'db> { let config = term::Config::default(); for diag in self.finalize(db) { - term::emit(&mut buffer, &config, db, &diag.to_cs(db)).unwrap(); + term::emit(&mut buffer, &config, &CsDbWrapper(db), &diag.to_cs(db)).unwrap(); } std::str::from_utf8(buffer.as_slice()).unwrap().to_string() diff --git a/crates/hir-analysis/Cargo.toml b/crates/hir-analysis/Cargo.toml index 19f87542d..3953c3edd 100644 --- a/crates/hir-analysis/Cargo.toml +++ b/crates/hir-analysis/Cargo.toml @@ -26,3 +26,5 @@ common = { path = "../common2", package = "fe-common2" } [dev-dependencies] codespan-reporting = "0.11" dir-test = "0.3" +# xxx move cs diagnostics utils +driver = { path = "../driver2", package = "fe-driver2" } diff --git a/crates/hir-analysis/src/name_resolution/mod.rs b/crates/hir-analysis/src/name_resolution/mod.rs index fe495ad47..dd0ae8aeb 100644 --- a/crates/hir-analysis/src/name_resolution/mod.rs +++ b/crates/hir-analysis/src/name_resolution/mod.rs @@ -11,8 +11,8 @@ use hir::{ analysis_pass::ModuleAnalysisPass, diagnostics::DiagnosticVoucher, hir_def::{ - scope_graph::ScopeId, Expr, ExprId, GenericArgListId, IdentId, IngotId, ItemKind, Partial, - Pat, PatId, PathId, TopLevelMod, TraitRefId, TypeId, + scope_graph::ScopeId, Expr, ExprId, GenericArgListId, IngotId, ItemKind, Pat, PatId, + PathId, PathSegmentId, TopLevelMod, TraitRefId, TypeId, }, visitor::prelude::*, }; @@ -51,7 +51,7 @@ pub fn resolve_path_early<'db>( /// contains some errors; it's always reported from [`PathAnalysisPass`]. pub fn resolve_segments_early<'db>( db: &'db dyn HirAnalysisDb, - segments: &[Partial>], + segments: &[PathSegmentId<'db>], scope: ScopeId<'db>, ) -> EarlyResolvedPath<'db> { // Obtain cache store for the given scope. @@ -218,7 +218,7 @@ struct EarlyPathVisitor<'db, 'a> { /// diagnostics. already_conflicted: FxHashSet>, } - +// xxx generic args? impl<'db, 'a> EarlyPathVisitor<'db, 'a> { fn new(db: &'db dyn HirAnalysisDb, importer: &'a DefaultImporter) -> Self { let resolver = name_resolver::NameResolver::new(db, importer); @@ -240,8 +240,12 @@ impl<'db, 'a> EarlyPathVisitor<'db, 'a> { bucket: NameResBucket<'db>, ) { let path_kind = self.path_ctxt.last().unwrap(); - let last_seg_idx = path.len(self.db.as_hir_db()) - 1; - let last_seg_ident = *path.segments(self.db.as_hir_db())[last_seg_idx].unwrap(); + let hir_db = self.db.as_hir_db(); + let last_seg_idx = path.len(hir_db) - 1; + let last_seg_ident = path + .last_segment(hir_db) + .and_then(|seg| seg.ident(hir_db).to_opt()) + .unwrap(); let span = span.segment(last_seg_idx).into(); if bucket.is_empty() { @@ -488,11 +492,12 @@ impl<'db, 'a> Visitor<'db> for EarlyPathVisitor<'db, 'a> { Err(err) => { let failed_at = err.failed_at; let span = ctxt.span().unwrap().segment(failed_at); - let ident = path.segments(self.db.as_hir_db())[failed_at]; + let hir_db = self.db.as_hir_db(); + let ident = path.segments(hir_db)[failed_at].ident(hir_db); let diag = match err.kind { NameResolutionError::NotFound => { - if path.len(self.db.as_hir_db()) == 1 + if path.len(hir_db) == 1 && matches!( self.path_ctxt.last().unwrap(), ExpectedPathKind::Expr | ExpectedPathKind::Pat @@ -536,9 +541,11 @@ impl<'db, 'a> Visitor<'db> for EarlyPathVisitor<'db, 'a> { }; if let Some((idx, res)) = resolved_path.find_invisible_segment(self.db) { + let hir_db = self.db.as_hir_db(); let span = ctxt.span().unwrap().segment(idx); - let ident = path.segments(self.db.as_hir_db())[idx].unwrap(); - let diag = NameResDiag::invisible(span.into(), *ident, res.derived_from(self.db)); + let ident = path.segments(hir_db)[idx].ident(hir_db); + let diag = + NameResDiag::invisible(span.into(), *ident.unwrap(), res.derived_from(self.db)); self.diags.push(diag); return; } @@ -572,6 +579,7 @@ impl ExpectedPathKind { } } + // xxx either::right == err? fn pick(self, bucket: NameResBucket) -> Either { debug_assert!(!bucket.is_empty()); diff --git a/crates/hir-analysis/src/name_resolution/path_resolver.rs b/crates/hir-analysis/src/name_resolution/path_resolver.rs index fe933eb99..cf63b6ff1 100644 --- a/crates/hir-analysis/src/name_resolution/path_resolver.rs +++ b/crates/hir-analysis/src/name_resolution/path_resolver.rs @@ -1,5 +1,5 @@ #![allow(unused)] -use hir::hir_def::{scope_graph::ScopeId, IdentId, Partial, PathId}; +use hir::hir_def::{scope_graph::ScopeId, IdentId, Partial, PathId, PathSegmentId}; use super::{ name_resolver::{ @@ -108,7 +108,7 @@ impl<'db, 'a, 'b, 'c> EarlyPathResolver<'db, 'a, 'b, 'c> { /// Resolves the given `segments` in the given `scope`. pub(super) fn resolve_segments( &mut self, - segments: &[Partial>], + segments: &[PathSegmentId<'db>], scope: ScopeId<'db>, ) -> PathResolutionResult<'db, EarlyResolvedPathWithTrajectory<'db>> { let mut i_path = IntermediatePath::new(self.db, segments, scope); @@ -155,16 +155,17 @@ impl<'db, 'a, 'b, 'c> EarlyPathResolver<'db, 'a, 'b, 'c> { } struct IntermediatePath<'db, 'a> { - path: &'a [Partial>], + path: &'a [PathSegmentId<'db>], idx: usize, current_res: NameRes<'db>, trajectory: Vec>, } +// xxx generic args? impl<'db, 'a> IntermediatePath<'db, 'a> { fn new( db: &'db dyn HirAnalysisDb, - path: &'a [Partial>], + path: &'a [PathSegmentId<'db>], scope: ScopeId<'db>, ) -> Self { let domain = NameDomain::from_scope(db, scope); @@ -181,17 +182,21 @@ impl<'db, 'a> IntermediatePath<'db, 'a> { } fn starts_with(&self, db: &dyn HirAnalysisDb, ident: IdentId) -> bool { - let Some(Partial::Present(first_seg)) = self.path.first() else { + let Some(first_seg) = self + .path + .first() + .and_then(|seg| seg.ident(db.as_hir_db()).to_opt()) + else { return false; }; - *first_seg == ident + first_seg == ident } /// Make a `NameQuery` to resolve the current segment. fn make_query(&self, db: &'db dyn HirAnalysisDb) -> PathResolutionResult<'db, NameQuery<'db>> { debug_assert!(self.state(db) != IntermediatePathState::Partial); - let Partial::Present(name) = self.path[self.idx] else { + let Partial::Present(name) = self.path[self.idx].ident(db.as_hir_db()) else { return Err(PathResolutionError::new( NameResolutionError::Invalid, self.idx, diff --git a/crates/hir-analysis/src/ty/ty_check/env.rs b/crates/hir-analysis/src/ty/ty_check/env.rs index 76b1f4fe2..18a77f80a 100644 --- a/crates/hir-analysis/src/ty/ty_check/env.rs +++ b/crates/hir-analysis/src/ty/ty_check/env.rs @@ -404,7 +404,9 @@ impl<'db> LocalBinding<'db> { else { unreachable!(); }; - *path.last_segment(hir_db).unwrap() + path.last_segment(hir_db) + .and_then(|seg| seg.ident(hir_db).to_opt()) + .unwrap() } Self::Param { idx, .. } => { diff --git a/crates/hir-analysis/src/ty/ty_check/expr.rs b/crates/hir-analysis/src/ty/ty_check/expr.rs index f31ecaa7e..769717c39 100644 --- a/crates/hir-analysis/src/ty/ty_check/expr.rs +++ b/crates/hir-analysis/src/ty/ty_check/expr.rs @@ -1,6 +1,7 @@ use either::Either; use hir::hir_def::{ - ArithBinOp, BinOp, Expr, ExprId, FieldIndex, IdentId, Partial, PathId, UnOp, VariantKind, + ArithBinOp, BinOp, Expr, ExprId, FieldIndex, IdentId, Partial, PathId, PathSegmentId, UnOp, + VariantKind, }; use super::{ @@ -251,7 +252,7 @@ impl<'db> TyChecker<'db> { } fn check_call(&mut self, expr: ExprId, expr_data: &Expr<'db>) -> ExprProp<'db> { - let Expr::Call(callee, generic_args, args) = expr_data else { + let Expr::Call(callee, args) = expr_data else { unreachable!() }; let callee_ty = self.fresh_ty(); @@ -261,20 +262,21 @@ impl<'db> TyChecker<'db> { return ExprProp::invalid(self.db); } - let mut callable = - match Callable::new(self.db, callee_ty, callee.lazy_span(self.body()).into()) { - Ok(callable) => callable, - Err(diag) => { - self.push_diag(diag); - return ExprProp::invalid(self.db); - } - }; + let callable = match Callable::new(self.db, callee_ty, callee.lazy_span(self.body()).into()) + { + Ok(callable) => callable, + Err(diag) => { + self.push_diag(diag); + return ExprProp::invalid(self.db); + } + }; let call_span = expr.lazy_span(self.body()).into_call_expr(); - if !callable.unify_generic_args(self, *generic_args, call_span.generic_args()) { - return ExprProp::invalid(self.db); - } + // xxx + // if !callable.unify_generic_args(self, *generic_args, call_span.generic_args()) { + // return ExprProp::invalid(self.db); + // } callable.check_args(self, args, call_span.args_moved(), None); @@ -948,7 +950,10 @@ pub(crate) trait TraitOps { fn trait_path<'db>(&self, db: &'db dyn HirAnalysisDb) -> PathId<'db> { let hir_db = db.as_hir_db(); let path = std_ops_path(db); - path.push(hir_db, self.trait_name(db)) + path.push( + hir_db, + PathSegmentId::from_ident(hir_db, self.trait_name(db)), + ) } fn trait_name<'db>(&self, db: &'db dyn HirAnalysisDb) -> IdentId<'db> { @@ -1067,7 +1072,7 @@ fn std_ops_path(db: &dyn HirAnalysisDb) -> PathId { let hir_db = db.as_hir_db(); let path_data: Vec<_> = ["std", "ops"] .into_iter() - .map(|s| Partial::Present(IdentId::new(hir_db, s.to_string()))) + .map(|s| PathSegmentId::from_ident(hir_db, IdentId::new(hir_db, s.to_string()))) .collect(); PathId::new(hir_db, path_data) diff --git a/crates/hir-analysis/src/ty/ty_check/path.rs b/crates/hir-analysis/src/ty/ty_check/path.rs index 4a178744b..eb2fb1b99 100644 --- a/crates/hir-analysis/src/ty/ty_check/path.rs +++ b/crates/hir-analysis/src/ty/ty_check/path.rs @@ -137,10 +137,7 @@ impl<'db, 'env> PathResolver<'db, 'env> { fn resolve_path(&mut self) -> ResolvedPathInBody<'db> { let hir_db = self.tc.db.as_hir_db(); - if self.path.is_ident(hir_db) { - let Some(ident) = self.path.last_segment(hir_db).to_opt() else { - return ResolvedPathInBody::Invalid; - }; + if let Some(ident) = self.path.as_ident(hir_db) { self.resolve_ident(ident) } else { let early_resolved_path = @@ -170,7 +167,12 @@ impl<'db, 'env> PathResolver<'db, 'env> { ResolvedPathInBody::Variant(..) => resolved, ResolvedPathInBody::Ty(ref ty) if ty.is_record(self.tc.db) => resolved, _ => { - if let Some(ident) = self.path.last_segment(hir_db).to_opt() { + if let Some(ident) = self + .path + .last_segment(hir_db) + .and_then(|seg| seg.ident(hir_db).to_opt()) + { + // xxx generic args ResolvedPathInBody::NewBinding(ident) } else { resolved @@ -276,9 +278,14 @@ impl<'db, 'env> PathResolver<'db, 'env> { } if unresolved_from == self.path.len(hir_db) - 1 { - let Some(name) = self.path.last_segment(hir_db).to_opt() else { + let Some(name) = self + .path + .last_segment(hir_db) + .and_then(|seg| seg.ident(hir_db).to_opt()) + else { return ResolvedPathInBody::Invalid; }; + // xxx generic args if let Some(resolved) = self.select_method_candidate(receiver_ty, name) { return resolved; } @@ -302,10 +309,15 @@ impl<'db, 'env> PathResolver<'db, 'env> { return ResolvedPathInBody::Diag(FuncBodyDiag::Ty(diag.into())); } - let Some(name) = self.path.last_segment(hir_db).to_opt() else { + let Some(name) = self + .path + .last_segment(hir_db) + .and_then(|seg| seg.ident(hir_db).to_opt()) + else { return ResolvedPathInBody::Invalid; }; + // xxx generic args let Some(trait_method) = trait_.methods(self.tc.db).get(&name) else { let span = self.span.segment(unresolved_from).into(); let diag = BodyDiag::method_not_found(self.tc.db, span, name, Either::Right(trait_)); diff --git a/crates/hir-analysis/test_files/ty_check/path_generic.fe b/crates/hir-analysis/test_files/ty_check/path_generic.fe new file mode 100644 index 000000000..faf6de6c1 --- /dev/null +++ b/crates/hir-analysis/test_files/ty_check/path_generic.fe @@ -0,0 +1,17 @@ +struct Foo { + t: T +} + +impl Foo { + fn method(self) -> T { + self.t + } +} + +fn foo() { + // Deciding the `Foo` type is not possible without a type argument for `Foo`. + let x = Foo::method() + + // We need this! + let x = Foo::method() +} diff --git a/crates/hir-analysis/tests/test_db.rs b/crates/hir-analysis/tests/test_db.rs index aa6f0ebfa..22c626c11 100644 --- a/crates/hir-analysis/tests/test_db.rs +++ b/crates/hir-analysis/tests/test_db.rs @@ -14,6 +14,7 @@ use common::{ input::{IngotKind, Version}, InputFile, InputIngot, }; +use driver::{diagnostics::ToCsDiag, CsDbWrapper}; use fe_hir_analysis::{ name_resolution::{DefConflictAnalysisPass, ImportAnalysisPass, PathAnalysisPass}, ty::{ @@ -29,6 +30,7 @@ use hir::{ ParsingPass, SpannedHirDb, }; use rustc_hash::FxHashMap; +use salsa::DbWithJar; type CodeSpanFileId = usize; @@ -38,7 +40,8 @@ type CodeSpanFileId = usize; hir::Jar, hir::SpannedJar, hir::LowerJar, - fe_hir_analysis::Jar + fe_hir_analysis::Jar, + driver::Jar )] pub struct HirAnalysisTestDb { storage: salsa::Storage, @@ -64,8 +67,27 @@ impl HirAnalysisTestDb { pub fn assert_no_diags(&self, top_mod: TopLevelMod) { let mut manager = initialize_analysis_pass(self); let diags = manager.run_on_module(top_mod); + if !diags.is_empty() { - panic!("this module contains errors") + let writer = BufferWriter::stderr(ColorChoice::Auto); + let mut buffer = writer.buffer(); + let config = term::Config::default(); + + // xxx copied from driver + let mut diags: Vec<_> = diags.iter().map(|d| d.to_complete(self)).collect(); + diags.sort_by(|lhs, rhs| match lhs.error_code.cmp(&rhs.error_code) { + std::cmp::Ordering::Equal => lhs.primary_span().cmp(&rhs.primary_span()), + ord => ord, + }); + + for diag in diags { + let cs_db = DbWithJar::::as_jar_db(self); + let cs_diag = &diag.to_cs(self); + term::emit(&mut buffer, &config, &CsDbWrapper(cs_db), &cs_diag).unwrap(); + } + eprintln!("{}", std::str::from_utf8(buffer.as_slice()).unwrap()); + + panic!("this module contains errors"); } } diff --git a/crates/hir/src/hir_def/expr.rs b/crates/hir/src/hir_def/expr.rs index ed41c3f78..ab6d25864 100644 --- a/crates/hir/src/hir_def/expr.rs +++ b/crates/hir/src/hir_def/expr.rs @@ -13,7 +13,7 @@ pub enum Expr<'db> { Bin(ExprId, ExprId, Partial), Un(ExprId, Partial), /// The first `ExprId` is the callee, the second is the arguments. - Call(ExprId, GenericArgListId<'db>, Vec>), + Call(ExprId, Vec>), /// The first `ExprId` is the method receiver, the second is the method /// name, the third is the arguments. MethodCall( @@ -110,7 +110,7 @@ pub enum ArithBinOp { BitAnd, /// `|` BitOr, - /// `^` + /// `^` BitXor, } @@ -170,11 +170,7 @@ impl<'db> CallArg<'db> { return None; }; - if path.is_ident(db) { - path.last_segment(db).to_opt() - } else { - None - } + path.as_ident(db) } } @@ -198,10 +194,6 @@ impl<'db> Field<'db> { return None; }; - if path.is_ident(db) { - path.last_segment(db).to_opt() - } else { - None - } + path.as_ident(db) } } diff --git a/crates/hir/src/hir_def/params.rs b/crates/hir/src/hir_def/params.rs index f6cd09e94..bd1921cc9 100644 --- a/crates/hir/src/hir_def/params.rs +++ b/crates/hir/src/hir_def/params.rs @@ -9,6 +9,10 @@ pub struct GenericArgListId<'db> { } impl<'db> GenericArgListId<'db> { + pub fn none(db: &'db dyn HirDb) -> Self { + Self::new(db, vec![], false) + } + pub fn len(self, db: &dyn HirDb) -> usize { self.data(db).len() } @@ -167,7 +171,7 @@ pub struct TraitRefId<'db> { /// The path to the trait. pub path: Partial>, /// The type arguments of the trait. - pub generic_args: Option>, + pub generic_args: Option>, // xxx remove } #[derive(Debug, Clone, PartialEq, Eq, Hash)] diff --git a/crates/hir/src/hir_def/pat.rs b/crates/hir/src/hir_def/pat.rs index ad9c7cbb6..bd121a911 100644 --- a/crates/hir/src/hir_def/pat.rs +++ b/crates/hir/src/hir_def/pat.rs @@ -47,9 +47,7 @@ impl<'db> RecordPatField<'db> { } match self.pat.data(db, body) { - Partial::Present(Pat::Path(Partial::Present(path), _)) if path.is_ident(db) => { - path.last_segment(db).to_opt() - } + Partial::Present(Pat::Path(Partial::Present(path), _)) => path.as_ident(db), _ => None, } } diff --git a/crates/hir/src/hir_def/path.rs b/crates/hir/src/hir_def/path.rs index 7b343557a..4b89d834b 100644 --- a/crates/hir/src/hir_def/path.rs +++ b/crates/hir/src/hir_def/path.rs @@ -1,37 +1,40 @@ -use super::IdentId; +use super::{GenericArgListId, IdentId}; use crate::{hir_def::Partial, HirDb}; #[salsa::interned] pub struct PathId<'db> { #[return_ref] - pub segments: Vec>>, + pub segments: Vec>, } impl<'db> PathId<'db> { - pub fn last_segment(self, db: &'db dyn HirDb) -> Partial { - self.segments(db).last().copied().unwrap_or_default() + pub fn last_segment(self, db: &'db dyn HirDb) -> Option { + self.segments(db).last().copied() } pub fn len(self, db: &dyn HirDb) -> usize { self.segments(db).len() } - pub fn is_ident(self, db: &dyn HirDb) -> bool { - self.len(db) == 1 + pub fn as_ident(self, db: &'db dyn HirDb) -> Option { + if self.len(db) == 1 { + self.last_segment(db).unwrap().ident(db).to_opt() + } else { + None + } } pub fn self_ty(db: &'db dyn HirDb) -> Self { - let self_ty = Partial::Present(IdentId::make_self_ty(db)); - Self::new(db, vec![self_ty]) + Self::from_ident(db, IdentId::make_self_ty(db)) } pub fn from_ident(db: &'db dyn HirDb, ident: IdentId<'db>) -> Self { - Self::new(db, vec![Partial::Present(ident)]) + Self::new(db, vec![PathSegmentId::from_ident(db, ident)]) } - pub fn push(self, db: &'db dyn HirDb, segment: IdentId<'db>) -> Self { + pub fn push(self, db: &'db dyn HirDb, segment: PathSegmentId<'db>) -> Self { let mut segments = self.segments(db).clone(); - segments.push(Partial::Present(segment)); + segments.push(segment); Self::new(db, segments) } @@ -39,10 +42,24 @@ impl<'db> PathId<'db> { self.segments(db) .iter() .map(|seg| { - seg.to_opt() + seg.ident(db) + .to_opt() .map_or("_".to_string(), |id| id.data(db).clone()) + // xxx print generic args }) .collect::>() .join("::") } } + +#[salsa::interned] +pub struct PathSegmentId<'db> { + pub ident: Partial>, + pub generic_args: GenericArgListId<'db>, +} + +impl<'db> PathSegmentId<'db> { + pub fn from_ident(db: &'db dyn HirDb, ident: IdentId<'db>) -> Self { + Self::new(db, Partial::Present(ident), GenericArgListId::none(db)) + } +} diff --git a/crates/hir/src/hir_def/types.rs b/crates/hir/src/hir_def/types.rs index d9a23715b..3879fa650 100644 --- a/crates/hir/src/hir_def/types.rs +++ b/crates/hir/src/hir_def/types.rs @@ -23,7 +23,7 @@ impl<'db> TypeId<'db> { #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum TypeKind<'db> { Ptr(Partial>), - Path(Partial>, GenericArgListId<'db>), + Path(Partial>, GenericArgListId<'db>), // xxx remove generic arg list SelfType(GenericArgListId<'db>), Tuple(TupleTypeId<'db>), /// The first `TypeId` is the element type, the second `Body` is the length. diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index ae3d9ddea..6d66b8dc9 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -38,6 +38,7 @@ pub struct Jar( hir_def::IntegerId<'_>, hir_def::StringId<'_>, hir_def::PathId<'_>, + hir_def::PathSegmentId<'_>, hir_def::FuncParamListId<'_>, hir_def::AttrListId<'_>, hir_def::WhereClauseId<'_>, diff --git a/crates/hir/src/lower/expr.rs b/crates/hir/src/lower/expr.rs index 2c291e066..8df114f93 100644 --- a/crates/hir/src/lower/expr.rs +++ b/crates/hir/src/lower/expr.rs @@ -53,8 +53,6 @@ impl<'db> Expr<'db> { ast::ExprKind::Call(call) => { let callee = Self::push_to_body_opt(ctxt, call.callee()); - let generic_args = - GenericArgListId::lower_ast_opt(ctxt.f_ctxt, call.generic_args()); let args = call .args() .map(|args| { @@ -63,7 +61,7 @@ impl<'db> Expr<'db> { .collect() }) .unwrap_or_default(); - Self::Call(callee, generic_args, args) + Self::Call(callee, args) } ast::ExprKind::MethodCall(method_call) => { diff --git a/crates/hir/src/lower/params.rs b/crates/hir/src/lower/params.rs index f8a6ea47d..e9c4a5e9f 100644 --- a/crates/hir/src/lower/params.rs +++ b/crates/hir/src/lower/params.rs @@ -17,7 +17,7 @@ impl<'db> GenericArgListId<'db> { ast: Option, ) -> Self { ast.map(|ast| Self::lower_ast(ctxt, ast)) - .unwrap_or_else(|| Self::new(ctxt.db(), Vec::new(), false)) + .unwrap_or_else(|| Self::none(ctxt.db())) } } diff --git a/crates/hir/src/lower/path.rs b/crates/hir/src/lower/path.rs index 366c2d31f..4d6b08b7d 100644 --- a/crates/hir/src/lower/path.rs +++ b/crates/hir/src/lower/path.rs @@ -1,7 +1,7 @@ -use parser::ast; +use crate::hir_def::{GenericArgListId, IdentId, Partial, PathId, PathSegmentId}; +use parser::ast::{self, GenericArgsOwner}; use super::FileLowerCtxt; -use crate::hir_def::{IdentId, Partial, PathId}; impl<'db> PathId<'db> { pub(super) fn lower_ast(ctxt: &mut FileLowerCtxt<'db>, ast: ast::Path) -> Self { @@ -9,7 +9,7 @@ impl<'db> PathId<'db> { let db = ctxt.db(); for seg in ast.into_iter() { - let segment = match seg.kind() { + let ident = match seg.kind() { Some(ast::PathSegmentKind::Ingot(_)) => Some(IdentId::make_ingot(db)), Some(ast::PathSegmentKind::Super(_)) => Some(IdentId::make_super(db)), Some(ast::PathSegmentKind::SelfTy(_)) => Some(IdentId::make_self_ty(db)), @@ -18,7 +18,9 @@ impl<'db> PathId<'db> { None => None, } .into(); - segments.push(segment); + + let generic_args = GenericArgListId::lower_ast_opt(ctxt, seg.generic_args()); + segments.push(PathSegmentId::new(ctxt.db(), ident, generic_args)); } Self::new(db, segments) diff --git a/crates/hir/src/span/expr.rs b/crates/hir/src/span/expr.rs index 771d03b8b..cb487e1d9 100644 --- a/crates/hir/src/span/expr.rs +++ b/crates/hir/src/span/expr.rs @@ -106,7 +106,6 @@ define_lazy_span_node!( LazyCallExprSpan, ast::CallExpr, @node { - (generic_args, generic_args, LazyGenericArgListSpan), (args, args, LazyCallArgListSpan), } ); diff --git a/crates/hir/src/span/path.rs b/crates/hir/src/span/path.rs index adaf0f977..e8d65f349 100644 --- a/crates/hir/src/span/path.rs +++ b/crates/hir/src/span/path.rs @@ -1,12 +1,13 @@ use parser::ast; -use super::{define_lazy_span_node, LazySpanAtom}; +use super::{define_lazy_span_node, params::LazyGenericArgListSpan, LazySpanAtom}; define_lazy_span_node!( LazyPathSpan, ast::Path, @idx { (segment, LazyPathSegmentSpan), + (generic_args, LazyGenericArgListSpan), } ); diff --git a/crates/hir/src/visitor.rs b/crates/hir/src/visitor.rs index b449b4bd4..1f66cc9f3 100644 --- a/crates/hir/src/visitor.rs +++ b/crates/hir/src/visitor.rs @@ -1004,16 +1004,11 @@ pub fn walk_expr<'db, V>( visit_node_in_body!(visitor, ctxt, expr_id, expr); } - Expr::Call(callee_id, generic_args, call_args) => { + Expr::Call(callee_id, call_args) => { visit_node_in_body!(visitor, ctxt, callee_id, expr); ctxt.with_new_ctxt( |span| span.into_call_expr(), |ctxt| { - ctxt.with_new_ctxt( - |span| span.generic_args_moved(), - |ctxt| visitor.visit_generic_arg_list(ctxt, *generic_args), - ); - ctxt.with_new_ctxt( |span| span.args_moved(), |ctxt| { @@ -1705,14 +1700,21 @@ pub fn walk_path<'db, V>( V: Visitor<'db> + ?Sized, { for (idx, segment) in path.segments(ctxt.db).iter().enumerate() { - if let Some(ident) = segment.to_opt() { + if let Some(ident) = segment.ident(ctxt.db).to_opt() { ctxt.with_new_ctxt( |span| span.segment_moved(idx).into_atom(), |ctxt| { visitor.visit_ident(ctxt, ident); }, - ) + ); } + let generic_args = segment.generic_args(ctxt.db); + ctxt.with_new_ctxt( + |span| span.generic_args_moved(idx), + |ctxt| { + visitor.visit_generic_arg_list(ctxt, generic_args); + }, + ); } } diff --git a/crates/parser2/src/ast/expr.rs b/crates/parser2/src/ast/expr.rs index e3a1a8dde..761d0380b 100644 --- a/crates/parser2/src/ast/expr.rs +++ b/crates/parser2/src/ast/expr.rs @@ -125,7 +125,6 @@ ast_node! { pub struct CallExpr, SK::CallExpr, } -impl GenericArgsOwner for CallExpr {} impl CallExpr { /// Returns the callee of the call expression. pub fn callee(&self) -> Option { @@ -724,20 +723,23 @@ mod tests { #[wasm_bindgen_test] fn call_expr() { let call_expr: CallExpr = parse_expr("foo(1, label: 2, 3 + 4)"); - - assert!(matches!( - call_expr.callee().unwrap().kind(), - ExprKind::Path(_) - )); - assert!(matches!( - call_expr + dbg!(&call_expr); + let ExprKind::Path(path) = call_expr.callee().unwrap().kind() else { + panic!(); + }; + // xxx lolol + assert_eq!( + path.path() + .unwrap() + .segments() + .next() + .unwrap() .generic_args() .unwrap() .into_iter() - .collect::>() - .len(), + .count(), 2 - )); + ); for (i, arg) in call_expr.args().unwrap().into_iter().enumerate() { match i { diff --git a/crates/parser2/src/ast/path.rs b/crates/parser2/src/ast/path.rs index caf8ed09e..eb35979d5 100644 --- a/crates/parser2/src/ast/path.rs +++ b/crates/parser2/src/ast/path.rs @@ -1,6 +1,6 @@ use rowan::ast::{support, AstNode}; -use super::{ast_node, AstChildren}; +use super::{ast_node, AstChildren, GenericArgsOwner}; use crate::{syntax_node::SyntaxToken, SyntaxKind as SK}; ast_node! { @@ -22,6 +22,7 @@ ast_node! { pub struct PathSegment, SK::PathSegment } +impl GenericArgsOwner for PathSegment {} impl PathSegment { pub fn kind(&self) -> Option { match self.syntax().first_child_or_token() { diff --git a/crates/parser2/src/ast/types.rs b/crates/parser2/src/ast/types.rs index 0bb8d9f89..b5c71859f 100644 --- a/crates/parser2/src/ast/types.rs +++ b/crates/parser2/src/ast/types.rs @@ -175,16 +175,19 @@ mod tests { for (i, segment) in path_ty.path().unwrap().segments().enumerate() { match i { 0 => assert_eq!(segment.ident().unwrap().text(), "Foo"), - 1 => assert_eq!(segment.ident().unwrap().text(), "Bar"), - _ => panic!(), - } - } - - let generic_args = path_ty.generic_args().unwrap(); - for (i, arg) in generic_args.iter().enumerate() { - match i { - 0 => assert!(matches!(arg.kind(), crate::ast::GenericArgKind::Type(_))), - 1 => assert!(matches!(arg.kind(), crate::ast::GenericArgKind::Const(_))), + 1 => { + assert_eq!(segment.ident().unwrap().text(), "Bar"); + let generic_args = segment.generic_args().unwrap(); + for (i, arg) in generic_args.iter().enumerate() { + match i { + 0 => assert!(matches!(arg.kind(), crate::ast::GenericArgKind::Type(_))), + 1 => { + assert!(matches!(arg.kind(), crate::ast::GenericArgKind::Const(_))) + } + _ => panic!(), + } + } + } _ => panic!(), } } diff --git a/crates/parser2/src/parser/expr.rs b/crates/parser2/src/parser/expr.rs index 054e5bbcd..9e241fe95 100644 --- a/crates/parser2/src/parser/expr.rs +++ b/crates/parser2/src/parser/expr.rs @@ -405,7 +405,7 @@ pub(crate) fn is_rshift(parser: &mut Parser) -> bool { parser.peek_two() == (Some(SyntaxKind::Gt), Some(SyntaxKind::Gt)) } -fn is_lt_eq(parser: &mut Parser) -> bool { +pub(crate) fn is_lt_eq(parser: &mut Parser) -> bool { parser.peek_two() == (Some(SyntaxKind::Lt), Some(SyntaxKind::Eq)) } @@ -486,6 +486,7 @@ fn is_call_expr(parser: &mut Parser) -> bool { parser.set_newline_as_trivia(false); let mut is_call = true; + // xxx check is_lshift, etc if parser.current_kind() == Some(SyntaxKind::Lt) { is_call &= parser .parse_ok(GenericArgListScope::default()) @@ -514,14 +515,16 @@ fn is_method_call(parser: &mut Parser) -> bool { return false; } - if parser.current_kind() == Some(SyntaxKind::Lt) - && !parser - .parse_ok(GenericArgListScope::default()) - .is_ok_and(identity) - { - return false; + if parser.current_kind() == Some(SyntaxKind::Lt) { + if is_lt_eq(parser) + || is_lshift(parser) + || !parser + .parse_ok(GenericArgListScope::default()) + .is_ok_and(identity) + { + return false; + } } - if parser.current_kind() != Some(SyntaxKind::LParen) { false } else { diff --git a/crates/parser2/src/parser/mod.rs b/crates/parser2/src/parser/mod.rs index c3a9af9c0..cce954a3e 100644 --- a/crates/parser2/src/parser/mod.rs +++ b/crates/parser2/src/parser/mod.rs @@ -228,6 +228,17 @@ impl Parser { res.map(|_| ok) } + pub fn parses_without_error(&mut self, mut scope: T) -> bool + where + T: Parse + 'static, + E: Recoverable, + { + let checkpoint = self.enter(scope.clone(), None); + let ok = scope.parse(self).is_ok(); + self.leave(checkpoint); + ok && !self.dry_run_states.last().unwrap().err // xxx + } + pub fn or_recover(&mut self, f: F) -> Result<(), Recovery> where F: FnOnce(&mut Self) -> Result<(), ParseError>, @@ -277,6 +288,8 @@ impl Parser { self.builder .start_node_at(checkpoint, scope.scope.syntax_kind().into()); self.builder.finish_node(); + } else { + self.dry_run_states.last_mut().unwrap().err |= scope.is_err; } scope.is_err } @@ -316,6 +329,7 @@ impl Parser { end_of_prev_token: self.end_of_prev_token, err_num: self.errors.len(), next_trivias: self.next_trivias.clone(), + err: false, }); let r = f(self); @@ -405,6 +419,8 @@ impl Parser { let mut unexpected = None; let mut match_scope_index = None; while let Some(kind) = self.current_kind() { + dbg!(kind); + dbg!(&self.parents); if let Some((scope_index, _)) = self .parents .iter() @@ -438,6 +454,8 @@ impl Parser { ), TextRange::new(start_pos, self.current_pos), )); + } else { + self.dry_run_states.last_mut().unwrap().err = true; } } @@ -676,6 +694,7 @@ struct DryRunState { err_num: usize, /// The stored trivias when the dry run started. next_trivias: VecDeque, + err: bool, } struct ScopeEntry { diff --git a/crates/parser2/src/parser/path.rs b/crates/parser2/src/parser/path.rs index 22dd77e0e..346706174 100644 --- a/crates/parser2/src/parser/path.rs +++ b/crates/parser2/src/parser/path.rs @@ -1,6 +1,14 @@ +use std::convert::identity; + use crate::{ParseError, SyntaxKind}; -use super::{define_scope, token_stream::TokenStream, Parser}; +use super::{ + define_scope, + expr::{is_lshift, is_lt_eq}, + param::GenericArgListScope, + token_stream::TokenStream, + Parser, +}; define_scope! { #[doc(hidden)] @@ -29,6 +37,21 @@ impl super::Parse for PathSegmentScope { match parser.current_kind() { Some(kind) if is_path_segment(kind) => { parser.bump(); + + if parser.current_kind() == Some(SyntaxKind::Lt) { + if !(is_lt_eq(parser) || is_lshift(parser)) + && parser.dry_run(|parser| { + // xxx parses_without_error? something else?? + parser + .parse_ok(GenericArgListScope::default()) + .is_ok_and(identity) + }) + { + parser + .parse(GenericArgListScope::default()) + .expect("dry_run suggests this will succeed"); + } + } Ok(()) } _ => Err(ParseError::expected( diff --git a/crates/parser2/test_files/error_recovery/exprs/call.snap b/crates/parser2/test_files/error_recovery/exprs/call.snap index dea6f8e5f..ecb375af6 100644 --- a/crates/parser2/test_files/error_recovery/exprs/call.snap +++ b/crates/parser2/test_files/error_recovery/exprs/call.snap @@ -39,30 +39,30 @@ Root@0..40 RParen@15..16 ")" Newline@16..18 "\n\n" CallExpr@18..39 - PathExpr@18..21 - Path@18..21 - PathSegment@18..21 + PathExpr@18..33 + Path@18..33 + PathSegment@18..33 Ident@18..21 "foo" - GenericArgList@21..33 - Lt@21..22 "<" - TypeGenericArg@22..25 - PathType@22..25 - Path@22..25 - PathSegment@22..25 - Ident@22..25 "i32" - Comma@25..26 "," - WhiteSpace@26..27 " " - TypeGenericArg@27..28 - PathType@27..28 - Path@27..28 - PathSegment@27..28 - Ident@27..28 "T" - WhiteSpace@28..29 " " - Error@29..30 - Ident@29..30 "E" - Comma@30..31 "," - WhiteSpace@31..32 " " - Gt@32..33 ">" + GenericArgList@21..33 + Lt@21..22 "<" + TypeGenericArg@22..25 + PathType@22..25 + Path@22..25 + PathSegment@22..25 + Ident@22..25 "i32" + Comma@25..26 "," + WhiteSpace@26..27 " " + TypeGenericArg@27..28 + PathType@27..28 + Path@27..28 + PathSegment@27..28 + Ident@27..28 "T" + WhiteSpace@28..29 " " + Error@29..30 + Ident@29..30 "E" + Comma@30..31 "," + WhiteSpace@31..32 " " + Gt@32..33 ">" CallArgList@33..39 LParen@33..34 "(" CallArg@34..35 diff --git a/crates/parser2/test_files/error_recovery/items/impl_.snap b/crates/parser2/test_files/error_recovery/items/impl_.snap index 131376c4b..8b7f27281 100644 --- a/crates/parser2/test_files/error_recovery/items/impl_.snap +++ b/crates/parser2/test_files/error_recovery/items/impl_.snap @@ -55,19 +55,19 @@ Root@0..56 ImplKw@39..43 "impl" WhiteSpace@43..44 " " PathType@44..52 - Path@44..47 - PathSegment@44..47 + Path@44..52 + PathSegment@44..52 Ident@44..47 "Foo" - GenericArgList@47..52 - Lt@47..48 "<" - TypeGenericArg@48..49 - PathType@48..49 - Path@48..49 - PathSegment@48..49 - Ident@48..49 "T" - Comma@49..50 "," - WhiteSpace@50..51 " " - Gt@51..52 ">" + GenericArgList@47..52 + Lt@47..48 "<" + TypeGenericArg@48..49 + PathType@48..49 + Path@48..49 + PathSegment@48..49 + Ident@48..49 "T" + Comma@49..50 "," + WhiteSpace@50..51 " " + Gt@51..52 ">" Newline@52..53 "\n" ImplItemList@53..56 LBrace@53..54 "{" diff --git a/crates/parser2/test_files/error_recovery/items/impl_trait.snap b/crates/parser2/test_files/error_recovery/items/impl_trait.snap index 5e30b5159..1cbb387cf 100644 --- a/crates/parser2/test_files/error_recovery/items/impl_trait.snap +++ b/crates/parser2/test_files/error_recovery/items/impl_trait.snap @@ -10,27 +10,27 @@ Root@0..90 ImplKw@0..4 "impl" WhiteSpace@4..5 " " TraitRef@5..14 - Path@5..6 - PathSegment@5..6 + Path@5..14 + PathSegment@5..14 Ident@5..6 "A" - GenericArgList@6..14 - Lt@6..7 "<" - TypeGenericArg@7..8 - PathType@7..8 - Path@7..8 - PathSegment@7..8 - Ident@7..8 "T" - Comma@8..9 "," - WhiteSpace@9..10 " " - TypeGenericArg@10..11 - PathType@10..11 - Path@10..11 - PathSegment@10..11 - Ident@10..11 "u" - Error@11..13 - RParen@11..12 ")" - RParen@12..13 ")" - Gt@13..14 ">" + GenericArgList@6..14 + Lt@6..7 "<" + TypeGenericArg@7..8 + PathType@7..8 + Path@7..8 + PathSegment@7..8 + Ident@7..8 "T" + Comma@8..9 "," + WhiteSpace@9..10 " " + TypeGenericArg@10..11 + PathType@10..11 + Path@10..11 + PathSegment@10..11 + Ident@10..11 "u" + Error@11..13 + RParen@11..12 ")" + RParen@12..13 ")" + Gt@13..14 ">" WhiteSpace@14..15 " " ForKw@15..18 "for" WhiteSpace@18..19 " " diff --git a/crates/parser2/test_files/error_recovery/items/type_.snap b/crates/parser2/test_files/error_recovery/items/type_.snap index 968b01aa9..94e140070 100644 --- a/crates/parser2/test_files/error_recovery/items/type_.snap +++ b/crates/parser2/test_files/error_recovery/items/type_.snap @@ -19,24 +19,24 @@ Root@0..72 Eq@15..16 "=" WhiteSpace@16..17 " " PathType@17..29 - Path@17..23 - PathSegment@17..23 + Path@17..29 + PathSegment@17..29 Ident@17..23 "Result" - GenericArgList@23..29 - Lt@23..24 "<" - TypeGenericArg@24..25 - PathType@24..25 - Path@24..25 - PathSegment@24..25 - Ident@24..25 "T" - Comma@25..26 "," - WhiteSpace@26..27 " " - TypeGenericArg@27..28 - PathType@27..28 - Path@27..28 - PathSegment@27..28 - Ident@27..28 "E" - Gt@28..29 ">" + GenericArgList@23..29 + Lt@23..24 "<" + TypeGenericArg@24..25 + PathType@24..25 + Path@24..25 + PathSegment@24..25 + Ident@24..25 "T" + Comma@25..26 "," + WhiteSpace@26..27 " " + TypeGenericArg@27..28 + PathType@27..28 + Path@27..28 + PathSegment@27..28 + Ident@27..28 "E" + Gt@28..29 ">" Newline@29..31 "\n\n" Item@31..70 TypeAlias@31..70 @@ -68,23 +68,23 @@ Root@0..72 Eq@56..57 "=" WhiteSpace@57..58 " " PathType@58..70 - Path@58..64 - PathSegment@58..64 + Path@58..70 + PathSegment@58..70 Ident@58..64 "Result" - GenericArgList@64..70 - Lt@64..65 "<" - TypeGenericArg@65..66 - PathType@65..66 - Path@65..66 - PathSegment@65..66 - Ident@65..66 "T" - Comma@66..67 "," - WhiteSpace@67..68 " " - TypeGenericArg@68..69 - PathType@68..69 - Path@68..69 - PathSegment@68..69 - Ident@68..69 "U" - Gt@69..70 ">" + GenericArgList@64..70 + Lt@64..65 "<" + TypeGenericArg@65..66 + PathType@65..66 + Path@65..66 + PathSegment@65..66 + Ident@65..66 "T" + Comma@66..67 "," + WhiteSpace@67..68 " " + TypeGenericArg@68..69 + PathType@68..69 + Path@68..69 + PathSegment@68..69 + Ident@68..69 "U" + Gt@69..70 ">" Newline@70..72 "\n\n" diff --git a/crates/parser2/test_files/syntax_node/exprs/call.fe b/crates/parser2/test_files/syntax_node/exprs/call.fe index c703e6fe5..499be49d3 100644 --- a/crates/parser2/test_files/syntax_node/exprs/call.fe +++ b/crates/parser2/test_files/syntax_node/exprs/call.fe @@ -8,5 +8,7 @@ foo(1, y: 2, z: 3) foo(val1: 2, val2: "String") foo<[u32; 1], {3 + 4}>(x: 1, y: 2) +foo::bar(x) + // Ths should be parsed as `(foo(1))`, not a tuple expression. -(foo < i32, (u32) > (1)) \ No newline at end of file +(foo < i32, (u32) > (1)) diff --git a/crates/parser2/test_files/syntax_node/exprs/call.snap b/crates/parser2/test_files/syntax_node/exprs/call.snap index 039785a82..045db8649 100644 --- a/crates/parser2/test_files/syntax_node/exprs/call.snap +++ b/crates/parser2/test_files/syntax_node/exprs/call.snap @@ -3,7 +3,7 @@ source: crates/parser2/tests/syntax_node.rs expression: node input_file: crates/parser2/test_files/syntax_node/exprs/call.fe --- -Root@0..270 +Root@0..290 CallExpr@0..5 PathExpr@0..3 Path@0..3 @@ -138,28 +138,28 @@ Root@0..270 RParen@85..86 ")" Newline@86..88 "\n\n" CallExpr@88..134 - PathExpr@88..91 - Path@88..91 - PathSegment@88..91 + PathExpr@88..109 + Path@88..109 + PathSegment@88..109 Ident@88..91 "foo" - GenericArgList@91..109 - Lt@91..92 "<" - TypeGenericArg@92..95 - PathType@92..95 - Path@92..95 - PathSegment@92..95 - Ident@92..95 "i32" - Comma@95..96 "," - WhiteSpace@96..97 " " - TypeGenericArg@97..108 - PathType@97..108 - Path@97..108 - PathSegment@97..100 - Ident@97..100 "foo" - Colon2@100..102 "::" - PathSegment@102..108 - Ident@102..108 "MyType" - Gt@108..109 ">" + GenericArgList@91..109 + Lt@91..92 "<" + TypeGenericArg@92..95 + PathType@92..95 + Path@92..95 + PathSegment@92..95 + Ident@92..95 "i32" + Comma@95..96 "," + WhiteSpace@96..97 " " + TypeGenericArg@97..108 + PathType@97..108 + Path@97..108 + PathSegment@97..100 + Ident@97..100 "foo" + Colon2@100..102 "::" + PathSegment@102..108 + Ident@102..108 "MyType" + Gt@108..109 ">" CallArgList@109..134 LParen@109..110 "(" CallArg@110..117 @@ -181,43 +181,43 @@ Root@0..270 RParen@133..134 ")" Newline@134..135 "\n" CallExpr@135..169 - PathExpr@135..138 - Path@135..138 - PathSegment@135..138 + PathExpr@135..157 + Path@135..157 + PathSegment@135..157 Ident@135..138 "foo" - GenericArgList@138..157 - Lt@138..139 "<" - TypeGenericArg@139..147 - ArrayType@139..147 - LBracket@139..140 "[" - PathType@140..143 - Path@140..143 - PathSegment@140..143 - Ident@140..143 "u32" - SemiColon@143..144 ";" - WhiteSpace@144..145 " " - LitExpr@145..146 - Lit@145..146 - Int@145..146 "1" - RBracket@146..147 "]" - Comma@147..148 "," - WhiteSpace@148..149 " " - ConstGenericArg@149..156 - BlockExpr@149..156 - LBrace@149..150 "{" - ExprStmt@150..155 - BinExpr@150..155 - LitExpr@150..151 - Lit@150..151 - Int@150..151 "3" - WhiteSpace@151..152 " " - Plus@152..153 "+" - WhiteSpace@153..154 " " - LitExpr@154..155 - Lit@154..155 - Int@154..155 "4" - RBrace@155..156 "}" - Gt@156..157 ">" + GenericArgList@138..157 + Lt@138..139 "<" + TypeGenericArg@139..147 + ArrayType@139..147 + LBracket@139..140 "[" + PathType@140..143 + Path@140..143 + PathSegment@140..143 + Ident@140..143 "u32" + SemiColon@143..144 ";" + WhiteSpace@144..145 " " + LitExpr@145..146 + Lit@145..146 + Int@145..146 "1" + RBracket@146..147 "]" + Comma@147..148 "," + WhiteSpace@148..149 " " + ConstGenericArg@149..156 + BlockExpr@149..156 + LBrace@149..150 "{" + ExprStmt@150..155 + BinExpr@150..155 + LitExpr@150..151 + Lit@150..151 + Int@150..151 "3" + WhiteSpace@151..152 " " + Plus@152..153 "+" + WhiteSpace@153..154 " " + LitExpr@154..155 + Lit@154..155 + Int@154..155 "4" + RBrace@155..156 "}" + Gt@156..157 ">" CallArgList@157..169 LParen@157..158 "(" CallArg@158..162 @@ -238,43 +238,76 @@ Root@0..270 Int@167..168 "2" RParen@168..169 ")" Newline@169..171 "\n\n" - Comment@171..245 "// Ths should be pars ..." - Newline@245..246 "\n" - ParenExpr@246..270 - LParen@246..247 "(" - CallExpr@247..269 - PathExpr@247..250 - Path@247..250 - PathSegment@247..250 - Ident@247..250 "foo" - WhiteSpace@250..251 " " - GenericArgList@251..265 - Lt@251..252 "<" - WhiteSpace@252..253 " " - TypeGenericArg@253..256 - PathType@253..256 - Path@253..256 - PathSegment@253..256 - Ident@253..256 "i32" - Comma@256..257 "," - WhiteSpace@257..258 " " - TypeGenericArg@258..263 - TupleType@258..263 - LParen@258..259 "(" - PathType@259..262 - Path@259..262 - PathSegment@259..262 - Ident@259..262 "u32" - RParen@262..263 ")" - WhiteSpace@263..264 " " - Gt@264..265 ">" - WhiteSpace@265..266 " " - CallArgList@266..269 - LParen@266..267 "(" - CallArg@267..268 - LitExpr@267..268 - Lit@267..268 - Int@267..268 "1" - RParen@268..269 ")" - RParen@269..270 ")" + CallExpr@171..188 + PathExpr@171..185 + Path@171..185 + PathSegment@171..174 + Ident@171..174 "foo" + Colon2@174..176 "::" + PathSegment@176..185 + Ident@176..179 "bar" + GenericArgList@179..185 + Lt@179..180 "<" + TypeGenericArg@180..181 + PathType@180..181 + Path@180..181 + PathSegment@180..181 + Ident@180..181 "T" + Comma@181..182 "," + WhiteSpace@182..183 " " + TypeGenericArg@183..184 + PathType@183..184 + Path@183..184 + PathSegment@183..184 + Ident@183..184 "U" + Gt@184..185 ">" + CallArgList@185..188 + LParen@185..186 "(" + CallArg@186..187 + PathExpr@186..187 + Path@186..187 + PathSegment@186..187 + Ident@186..187 "x" + RParen@187..188 ")" + Newline@188..190 "\n\n" + Comment@190..264 "// Ths should be pars ..." + Newline@264..265 "\n" + ParenExpr@265..289 + LParen@265..266 "(" + CallExpr@266..288 + PathExpr@266..284 + Path@266..284 + PathSegment@266..284 + Ident@266..269 "foo" + WhiteSpace@269..270 " " + GenericArgList@270..284 + Lt@270..271 "<" + WhiteSpace@271..272 " " + TypeGenericArg@272..275 + PathType@272..275 + Path@272..275 + PathSegment@272..275 + Ident@272..275 "i32" + Comma@275..276 "," + WhiteSpace@276..277 " " + TypeGenericArg@277..282 + TupleType@277..282 + LParen@277..278 "(" + PathType@278..281 + Path@278..281 + PathSegment@278..281 + Ident@278..281 "u32" + RParen@281..282 ")" + WhiteSpace@282..283 " " + Gt@283..284 ">" + WhiteSpace@284..285 " " + CallArgList@285..288 + LParen@285..286 "(" + CallArg@286..287 + LitExpr@286..287 + Lit@286..287 + Int@286..287 "1" + RParen@287..288 ")" + RParen@288..289 ")" + Newline@289..290 "\n" diff --git a/crates/parser2/test_files/syntax_node/items/enums.snap b/crates/parser2/test_files/syntax_node/items/enums.snap index dea236660..c86189673 100644 --- a/crates/parser2/test_files/syntax_node/items/enums.snap +++ b/crates/parser2/test_files/syntax_node/items/enums.snap @@ -210,20 +210,20 @@ Root@0..493 WhiteSpace@253..254 " " WherePredicate@254..272 PathType@254..265 - Path@254..262 + Path@254..265 PathSegment@254..257 Ident@254..257 "Foo" Colon2@257..259 "::" - PathSegment@259..262 + PathSegment@259..265 Ident@259..262 "Bar" - GenericArgList@262..265 - Lt@262..263 "<" - TypeGenericArg@263..264 - PathType@263..264 - Path@263..264 - PathSegment@263..264 - Ident@263..264 "T" - Gt@264..265 ">" + GenericArgList@262..265 + Lt@262..263 "<" + TypeGenericArg@263..264 + PathType@263..264 + Path@263..264 + PathSegment@263..264 + Ident@263..264 "T" + Gt@264..265 ">" TypeBoundList@265..272 Colon@265..266 ":" WhiteSpace@266..267 " " @@ -402,17 +402,17 @@ Root@0..493 TupleType@426..432 LParen@426..427 "(" PathType@427..431 - Path@427..428 - PathSegment@427..428 + Path@427..431 + PathSegment@427..431 Ident@427..428 "U" - GenericArgList@428..431 - Lt@428..429 "<" - TypeGenericArg@429..430 - PathType@429..430 - Path@429..430 - PathSegment@429..430 - Ident@429..430 "T" - Gt@430..431 ">" + GenericArgList@428..431 + Lt@428..429 "<" + TypeGenericArg@429..430 + PathType@429..430 + Path@429..430 + PathSegment@429..430 + Ident@429..430 "T" + Gt@430..431 ">" RParen@431..432 ")" Newline@432..433 "\n" RBrace@433..434 "}" diff --git a/crates/parser2/test_files/syntax_node/items/func.snap b/crates/parser2/test_files/syntax_node/items/func.snap index 52e9c4036..63ea1d801 100644 --- a/crates/parser2/test_files/syntax_node/items/func.snap +++ b/crates/parser2/test_files/syntax_node/items/func.snap @@ -198,17 +198,17 @@ Root@0..351 Colon@213..214 ":" WhiteSpace@214..215 " " PathType@215..224 - Path@215..221 - PathSegment@215..221 + Path@215..224 + PathSegment@215..224 Ident@215..221 "Option" - GenericArgList@221..224 - Lt@221..222 "<" - TypeGenericArg@222..223 - PathType@222..223 - Path@222..223 - PathSegment@222..223 - Ident@222..223 "U" - Gt@223..224 ">" + GenericArgList@221..224 + Lt@221..222 "<" + TypeGenericArg@222..223 + PathType@222..223 + Path@222..223 + PathSegment@222..223 + Ident@222..223 "U" + Gt@223..224 ">" RParen@224..225 ")" WhiteSpace@225..226 " " Arrow@226..228 "->" @@ -224,17 +224,17 @@ Root@0..351 WhiteSpace@240..241 " " WherePredicate@241..257 PathType@241..250 - Path@241..247 - PathSegment@241..247 + Path@241..250 + PathSegment@241..250 Ident@241..247 "Result" - GenericArgList@247..250 - Lt@247..248 "<" - TypeGenericArg@248..249 - PathType@248..249 - Path@248..249 - PathSegment@248..249 - Ident@248..249 "T" - Gt@249..250 ">" + GenericArgList@247..250 + Lt@247..248 "<" + TypeGenericArg@248..249 + PathType@248..249 + Path@248..249 + PathSegment@248..249 + Ident@248..249 "T" + Gt@249..250 ">" TypeBoundList@250..257 Colon@250..251 ":" WhiteSpace@251..252 " " @@ -248,17 +248,17 @@ Root@0..351 WhiteSpace@259..269 " " WherePredicate@269..285 PathType@269..278 - Path@269..275 - PathSegment@269..275 + Path@269..278 + PathSegment@269..278 Ident@269..275 "Option" - GenericArgList@275..278 - Lt@275..276 "<" - TypeGenericArg@276..277 - PathType@276..277 - Path@276..277 - PathSegment@276..277 - Ident@276..277 "U" - Gt@277..278 ">" + GenericArgList@275..278 + Lt@275..276 "<" + TypeGenericArg@276..277 + PathType@276..277 + Path@276..277 + PathSegment@276..277 + Ident@276..277 "U" + Gt@277..278 ">" TypeBoundList@278..285 Colon@278..279 ":" WhiteSpace@279..280 " " @@ -301,47 +301,47 @@ Root@0..351 Colon@313..314 ":" WhiteSpace@314..315 " " PathType@315..329 - Path@315..323 - PathSegment@315..323 + Path@315..329 + PathSegment@315..329 Ident@315..323 "MyStruct" - GenericArgList@323..329 - Lt@323..324 "<" - TypeGenericArg@324..325 - PathType@324..325 - Path@324..325 - PathSegment@324..325 - Ident@324..325 "T" - Comma@325..326 "," - WhiteSpace@326..327 " " - TypeGenericArg@327..328 - PathType@327..328 - Path@327..328 - PathSegment@327..328 - Ident@327..328 "U" - Gt@328..329 ">" + GenericArgList@323..329 + Lt@323..324 "<" + TypeGenericArg@324..325 + PathType@324..325 + Path@324..325 + PathSegment@324..325 + Ident@324..325 "T" + Comma@325..326 "," + WhiteSpace@326..327 " " + TypeGenericArg@327..328 + PathType@327..328 + Path@327..328 + PathSegment@327..328 + Ident@327..328 "U" + Gt@328..329 ">" RParen@329..330 ")" WhiteSpace@330..331 " " Arrow@331..333 "->" WhiteSpace@333..334 " " PathType@334..348 - Path@334..340 - PathSegment@334..340 + Path@334..348 + PathSegment@334..348 Ident@334..340 "Result" - GenericArgList@340..348 - Lt@340..341 "<" - TypeGenericArg@341..342 - PathType@341..342 - Path@341..342 - PathSegment@341..342 - Ident@341..342 "T" - Comma@342..343 "," - WhiteSpace@343..344 " " - TypeGenericArg@344..347 - PathType@344..347 - Path@344..347 - PathSegment@344..347 - Ident@344..347 "Err" - Gt@347..348 ">" + GenericArgList@340..348 + Lt@340..341 "<" + TypeGenericArg@341..342 + PathType@341..342 + Path@341..342 + PathSegment@341..342 + Ident@341..342 "T" + Comma@342..343 "," + WhiteSpace@343..344 " " + TypeGenericArg@344..347 + PathType@344..347 + Path@344..347 + PathSegment@344..347 + Ident@344..347 "Err" + Gt@347..348 ">" WhiteSpace@348..349 " " BlockExpr@349..351 LBrace@349..350 "{" diff --git a/crates/parser2/test_files/syntax_node/items/impl.snap b/crates/parser2/test_files/syntax_node/items/impl.snap index da14d9275..fdf40976f 100644 --- a/crates/parser2/test_files/syntax_node/items/impl.snap +++ b/crates/parser2/test_files/syntax_node/items/impl.snap @@ -23,20 +23,20 @@ Root@0..272 Gt@11..12 ">" WhiteSpace@12..13 " " PathType@13..24 - Path@13..21 + Path@13..24 PathSegment@13..16 Ident@13..16 "Foo" Colon2@16..18 "::" - PathSegment@18..21 + PathSegment@18..24 Ident@18..21 "Bar" - GenericArgList@21..24 - Lt@21..22 "<" - TypeGenericArg@22..23 - PathType@22..23 - Path@22..23 - PathSegment@22..23 - Ident@22..23 "T" - Gt@23..24 ">" + GenericArgList@21..24 + Lt@21..22 "<" + TypeGenericArg@22..23 + PathType@22..23 + Path@22..23 + PathSegment@22..23 + Ident@22..23 "T" + Gt@23..24 ">" WhiteSpace@24..25 " " ImplItemList@25..137 LBrace@25..26 "{" @@ -123,17 +123,17 @@ Root@0..272 Gt@145..146 ">" WhiteSpace@146..147 " " PathType@147..153 - Path@147..150 - PathSegment@147..150 + Path@147..153 + PathSegment@147..153 Ident@147..150 "Foo" - GenericArgList@150..153 - Lt@150..151 "<" - TypeGenericArg@151..152 - PathType@151..152 - Path@151..152 - PathSegment@151..152 - Ident@151..152 "T" - Gt@152..153 ">" + GenericArgList@150..153 + Lt@150..151 "<" + TypeGenericArg@151..152 + PathType@151..152 + Path@151..152 + PathSegment@151..152 + Ident@151..152 "T" + Gt@152..153 ">" WhiteSpace@153..154 " " Newline@154..155 "\n" WhereClause@155..174 @@ -141,17 +141,17 @@ Root@0..272 WhiteSpace@160..161 " " WherePredicate@161..174 PathType@161..167 - Path@161..164 - PathSegment@161..164 + Path@161..167 + PathSegment@161..167 Ident@161..164 "Foo" - GenericArgList@164..167 - Lt@164..165 "<" - TypeGenericArg@165..166 - PathType@165..166 - Path@165..166 - PathSegment@165..166 - Ident@165..166 "T" - Gt@166..167 ">" + GenericArgList@164..167 + Lt@164..165 "<" + TypeGenericArg@165..166 + PathType@165..166 + Path@165..166 + PathSegment@165..166 + Ident@165..166 "T" + Gt@166..167 ">" TypeBoundList@167..174 Colon@167..168 ":" WhiteSpace@168..169 " " @@ -178,17 +178,17 @@ Root@0..272 WhiteSpace@190..191 " " TypeBound@191..197 TraitRef@191..197 - Path@191..194 - PathSegment@191..194 + Path@191..197 + PathSegment@191..197 Ident@191..194 "Add" - GenericArgList@194..197 - Lt@194..195 "<" - TypeGenericArg@195..196 - PathType@195..196 - Path@195..196 - PathSegment@195..196 - Ident@195..196 "T" - Gt@196..197 ">" + GenericArgList@194..197 + Lt@194..195 "<" + TypeGenericArg@195..196 + PathType@195..196 + Path@195..196 + PathSegment@195..196 + Ident@195..196 "T" + Gt@196..197 ">" Gt@197..198 ">" FuncParamList@198..212 LParen@198..199 "(" diff --git a/crates/parser2/test_files/syntax_node/items/impl_trait.snap b/crates/parser2/test_files/syntax_node/items/impl_trait.snap index cba9fbebb..f1d68e171 100644 --- a/crates/parser2/test_files/syntax_node/items/impl_trait.snap +++ b/crates/parser2/test_files/syntax_node/items/impl_trait.snap @@ -15,32 +15,32 @@ Root@0..334 Gt@6..7 ">" WhiteSpace@7..8 " " TraitRef@8..16 - Path@8..13 - PathSegment@8..13 + Path@8..16 + PathSegment@8..16 Ident@8..13 "Trait" - GenericArgList@13..16 - Lt@13..14 "<" - TypeGenericArg@14..15 - PathType@14..15 - Path@14..15 - PathSegment@14..15 - Ident@14..15 "T" - Gt@15..16 ">" + GenericArgList@13..16 + Lt@13..14 "<" + TypeGenericArg@14..15 + PathType@14..15 + Path@14..15 + PathSegment@14..15 + Ident@14..15 "T" + Gt@15..16 ">" WhiteSpace@16..17 " " ForKw@17..20 "for" WhiteSpace@20..21 " " PathType@21..25 - Path@21..22 - PathSegment@21..22 + Path@21..25 + PathSegment@21..25 Ident@21..22 "F" - GenericArgList@22..25 - Lt@22..23 "<" - TypeGenericArg@23..24 - PathType@23..24 - Path@23..24 - PathSegment@23..24 - Ident@23..24 "T" - Gt@24..25 ">" + GenericArgList@22..25 + Lt@22..23 "<" + TypeGenericArg@23..24 + PathType@23..24 + Path@23..24 + PathSegment@23..24 + Ident@23..24 "T" + Gt@24..25 ">" WhiteSpace@25..26 " " ImplTraitItemList@26..67 LBrace@26..27 "{" @@ -84,39 +84,39 @@ Root@0..334 Gt@78..79 ">" WhiteSpace@79..80 " " TraitRef@80..91 - Path@80..85 - PathSegment@80..85 + Path@80..91 + PathSegment@80..91 Ident@80..85 "Trait" - GenericArgList@85..91 - Lt@85..86 "<" - TypeGenericArg@86..87 - PathType@86..87 - Path@86..87 - PathSegment@86..87 - Ident@86..87 "T" - Comma@87..88 "," - WhiteSpace@88..89 " " - TypeGenericArg@89..90 - PathType@89..90 - Path@89..90 - PathSegment@89..90 - Ident@89..90 "U" - Gt@90..91 ">" + GenericArgList@85..91 + Lt@85..86 "<" + TypeGenericArg@86..87 + PathType@86..87 + Path@86..87 + PathSegment@86..87 + Ident@86..87 "T" + Comma@87..88 "," + WhiteSpace@88..89 " " + TypeGenericArg@89..90 + PathType@89..90 + Path@89..90 + PathSegment@89..90 + Ident@89..90 "U" + Gt@90..91 ">" WhiteSpace@91..92 " " ForKw@92..95 "for" WhiteSpace@95..96 " " PathType@96..100 - Path@96..97 - PathSegment@96..97 + Path@96..100 + PathSegment@96..100 Ident@96..97 "F" - GenericArgList@97..100 - Lt@97..98 "<" - TypeGenericArg@98..99 - PathType@98..99 - Path@98..99 - PathSegment@98..99 - Ident@98..99 "T" - Gt@99..100 ">" + GenericArgList@97..100 + Lt@97..98 "<" + TypeGenericArg@98..99 + PathType@98..99 + Path@98..99 + PathSegment@98..99 + Ident@98..99 "T" + Gt@99..100 ">" Newline@100..101 "\n" WhereClause@101..129 WhereKw@101..106 "where" @@ -168,17 +168,17 @@ Root@0..334 WhiteSpace@145..146 " " TypeBound@146..159 TraitRef@146..159 - Path@146..156 - PathSegment@146..156 + Path@146..159 + PathSegment@146..159 Ident@146..156 "OtherTrait" - GenericArgList@156..159 - Lt@156..157 "<" - TypeGenericArg@157..158 - PathType@157..158 - Path@157..158 - PathSegment@157..158 - Ident@157..158 "U" - Gt@158..159 ">" + GenericArgList@156..159 + Lt@156..157 "<" + TypeGenericArg@157..158 + PathType@157..158 + Path@157..158 + PathSegment@157..158 + Ident@157..158 "U" + Gt@158..159 ">" Gt@159..160 ">" FuncParamList@160..166 LParen@160..161 "(" @@ -198,18 +198,18 @@ Root@0..334 WhiteSpace@169..177 " " ExprStmt@177..197 CallExpr@177..197 - PathExpr@177..189 - Path@177..189 - PathSegment@177..189 + PathExpr@177..194 + Path@177..194 + PathSegment@177..194 Ident@177..189 "do_something" - GenericArgList@189..194 - Lt@189..190 "<" - TypeGenericArg@190..193 - PathType@190..193 - Path@190..193 - PathSegment@190..193 - Ident@190..193 "i32" - Gt@193..194 ">" + GenericArgList@189..194 + Lt@189..190 "<" + TypeGenericArg@190..193 + PathType@190..193 + Path@190..193 + PathSegment@190..193 + Ident@190..193 "i32" + Gt@193..194 ">" CallArgList@194..197 LParen@194..195 "(" CallArg@195..196 @@ -246,39 +246,39 @@ Root@0..334 Gt@223..224 ">" WhiteSpace@224..225 " " TraitRef@225..236 - Path@225..230 - PathSegment@225..230 + Path@225..236 + PathSegment@225..236 Ident@225..230 "Trait" - GenericArgList@230..236 - Lt@230..231 "<" - TypeGenericArg@231..232 - PathType@231..232 - Path@231..232 - PathSegment@231..232 - Ident@231..232 "T" - Comma@232..233 "," - WhiteSpace@233..234 " " - TypeGenericArg@234..235 - PathType@234..235 - Path@234..235 - PathSegment@234..235 - Ident@234..235 "U" - Gt@235..236 ">" + GenericArgList@230..236 + Lt@230..231 "<" + TypeGenericArg@231..232 + PathType@231..232 + Path@231..232 + PathSegment@231..232 + Ident@231..232 "T" + Comma@232..233 "," + WhiteSpace@233..234 " " + TypeGenericArg@234..235 + PathType@234..235 + Path@234..235 + PathSegment@234..235 + Ident@234..235 "U" + Gt@235..236 ">" WhiteSpace@236..237 " " ForKw@237..240 "for" WhiteSpace@240..241 " " PathType@241..245 - Path@241..242 - PathSegment@241..242 + Path@241..245 + PathSegment@241..245 Ident@241..242 "F" - GenericArgList@242..245 - Lt@242..243 "<" - TypeGenericArg@243..244 - PathType@243..244 - Path@243..244 - PathSegment@243..244 - Ident@243..244 "U" - Gt@244..245 ">" + GenericArgList@242..245 + Lt@242..243 "<" + TypeGenericArg@243..244 + PathType@243..244 + Path@243..244 + PathSegment@243..244 + Ident@243..244 "U" + Gt@244..245 ">" Newline@245..246 "\n" WhereClause@246..258 WhereKw@246..251 "where" @@ -314,17 +314,17 @@ Root@0..334 WhiteSpace@274..275 " " TypeBound@275..288 TraitRef@275..288 - Path@275..285 - PathSegment@275..285 + Path@275..288 + PathSegment@275..288 Ident@275..285 "OtherTrait" - GenericArgList@285..288 - Lt@285..286 "<" - TypeGenericArg@286..287 - PathType@286..287 - Path@286..287 - PathSegment@286..287 - Ident@286..287 "U" - Gt@287..288 ">" + GenericArgList@285..288 + Lt@285..286 "<" + TypeGenericArg@286..287 + PathType@286..287 + Path@286..287 + PathSegment@286..287 + Ident@286..287 "U" + Gt@287..288 ">" Gt@288..289 ">" FuncParamList@289..295 LParen@289..290 "(" @@ -344,18 +344,18 @@ Root@0..334 WhiteSpace@298..306 " " ExprStmt@306..326 CallExpr@306..326 - PathExpr@306..318 - Path@306..318 - PathSegment@306..318 + PathExpr@306..323 + Path@306..323 + PathSegment@306..323 Ident@306..318 "do_something" - GenericArgList@318..323 - Lt@318..319 "<" - TypeGenericArg@319..322 - PathType@319..322 - Path@319..322 - PathSegment@319..322 - Ident@319..322 "i32" - Gt@322..323 ">" + GenericArgList@318..323 + Lt@318..319 "<" + TypeGenericArg@319..322 + PathType@319..322 + Path@319..322 + PathSegment@319..322 + Ident@319..322 "i32" + Gt@322..323 ">" CallArgList@323..326 LParen@323..324 "(" CallArg@324..325 diff --git a/crates/parser2/test_files/syntax_node/items/path_generic.fe b/crates/parser2/test_files/syntax_node/items/path_generic.fe new file mode 100644 index 000000000..faf6de6c1 --- /dev/null +++ b/crates/parser2/test_files/syntax_node/items/path_generic.fe @@ -0,0 +1,17 @@ +struct Foo { + t: T +} + +impl Foo { + fn method(self) -> T { + self.t + } +} + +fn foo() { + // Deciding the `Foo` type is not possible without a type argument for `Foo`. + let x = Foo::method() + + // We need this! + let x = Foo::method() +} diff --git a/crates/parser2/test_files/syntax_node/items/path_generic.snap b/crates/parser2/test_files/syntax_node/items/path_generic.snap new file mode 100644 index 000000000..16997e91e --- /dev/null +++ b/crates/parser2/test_files/syntax_node/items/path_generic.snap @@ -0,0 +1,169 @@ +--- +source: crates/parser2/tests/syntax_node.rs +expression: node +input_file: crates/parser2/test_files/syntax_node/items/path_generic.fe +--- +Root@0..270 + ItemList@0..269 + Item@0..26 + Struct@0..26 + StructKw@0..6 "struct" + WhiteSpace@6..7 " " + Ident@7..10 "Foo" + GenericParamList@10..13 + Lt@10..11 "<" + TypeGenericParam@11..12 + Ident@11..12 "T" + Gt@12..13 ">" + WhiteSpace@13..14 " " + RecordFieldDefList@14..26 + LBrace@14..15 "{" + Newline@15..16 "\n" + WhiteSpace@16..20 " " + RecordFieldDef@20..24 + Ident@20..21 "t" + Colon@21..22 ":" + WhiteSpace@22..23 " " + PathType@23..24 + Path@23..24 + PathSegment@23..24 + Ident@23..24 "T" + Newline@24..25 "\n" + RBrace@25..26 "}" + Newline@26..28 "\n\n" + Item@28..94 + Impl@28..94 + ImplKw@28..32 "impl" + GenericParamList@32..35 + Lt@32..33 "<" + TypeGenericParam@33..34 + Ident@33..34 "T" + Gt@34..35 ">" + WhiteSpace@35..36 " " + PathType@36..42 + Path@36..42 + PathSegment@36..42 + Ident@36..39 "Foo" + GenericArgList@39..42 + Lt@39..40 "<" + TypeGenericArg@40..41 + PathType@40..41 + Path@40..41 + PathSegment@40..41 + Ident@40..41 "T" + Gt@41..42 ">" + WhiteSpace@42..43 " " + ImplItemList@43..94 + LBrace@43..44 "{" + Newline@44..45 "\n" + WhiteSpace@45..49 " " + Func@49..92 + FnKw@49..51 "fn" + WhiteSpace@51..52 " " + Ident@52..58 "method" + FuncParamList@58..64 + LParen@58..59 "(" + FnParam@59..63 + SelfKw@59..63 "self" + RParen@63..64 ")" + WhiteSpace@64..65 " " + Arrow@65..67 "->" + WhiteSpace@67..68 " " + PathType@68..69 + Path@68..69 + PathSegment@68..69 + Ident@68..69 "T" + WhiteSpace@69..70 " " + BlockExpr@70..92 + LBrace@70..71 "{" + Newline@71..72 "\n" + WhiteSpace@72..80 " " + ExprStmt@80..86 + FieldExpr@80..86 + PathExpr@80..84 + Path@80..84 + PathSegment@80..84 + SelfKw@80..84 "self" + Dot@84..85 "." + Ident@85..86 "t" + Newline@86..87 "\n" + WhiteSpace@87..91 " " + RBrace@91..92 "}" + Newline@92..93 "\n" + RBrace@93..94 "}" + Newline@94..96 "\n\n" + Item@96..269 + Func@96..269 + FnKw@96..98 "fn" + WhiteSpace@98..99 " " + Ident@99..102 "foo" + FuncParamList@102..104 + LParen@102..103 "(" + RParen@103..104 ")" + WhiteSpace@104..105 " " + BlockExpr@105..269 + LBrace@105..106 "{" + Newline@106..107 "\n" + WhiteSpace@107..111 " " + Comment@111..188 "// Deciding the `Foo` ..." + Newline@188..189 "\n" + WhiteSpace@189..193 " " + LetStmt@193..214 + LetKw@193..196 "let" + WhiteSpace@196..197 " " + PathPat@197..198 + Path@197..198 + PathSegment@197..198 + Ident@197..198 "x" + WhiteSpace@198..199 " " + Eq@199..200 "=" + WhiteSpace@200..201 " " + CallExpr@201..214 + PathExpr@201..212 + Path@201..212 + PathSegment@201..204 + Ident@201..204 "Foo" + Colon2@204..206 "::" + PathSegment@206..212 + Ident@206..212 "method" + CallArgList@212..214 + LParen@212..213 "(" + RParen@213..214 ")" + Newline@214..216 "\n\n" + WhiteSpace@216..220 " " + Comment@220..236 "// We need this!" + Newline@236..237 "\n" + WhiteSpace@237..241 " " + LetStmt@241..267 + LetKw@241..244 "let" + WhiteSpace@244..245 " " + PathPat@245..246 + Path@245..246 + PathSegment@245..246 + Ident@245..246 "x" + WhiteSpace@246..247 " " + Eq@247..248 "=" + WhiteSpace@248..249 " " + CallExpr@249..267 + PathExpr@249..265 + Path@249..265 + PathSegment@249..257 + Ident@249..252 "Foo" + GenericArgList@252..257 + Lt@252..253 "<" + TypeGenericArg@253..256 + PathType@253..256 + Path@253..256 + PathSegment@253..256 + Ident@253..256 "i32" + Gt@256..257 ">" + Colon2@257..259 "::" + PathSegment@259..265 + Ident@259..265 "method" + CallArgList@265..267 + LParen@265..266 "(" + RParen@266..267 ")" + Newline@267..268 "\n" + RBrace@268..269 "}" + Newline@269..270 "\n" + diff --git a/crates/parser2/test_files/syntax_node/items/trait.snap b/crates/parser2/test_files/syntax_node/items/trait.snap index 4d29724f5..ea89210e3 100644 --- a/crates/parser2/test_files/syntax_node/items/trait.snap +++ b/crates/parser2/test_files/syntax_node/items/trait.snap @@ -294,17 +294,17 @@ Root@0..652 Colon@341..342 ":" WhiteSpace@342..343 " " PathType@343..352 - Path@343..349 - PathSegment@343..349 + Path@343..352 + PathSegment@343..352 Ident@343..349 "Parser" - GenericArgList@349..352 - Lt@349..350 "<" - TypeGenericArg@350..351 - PathType@350..351 - Path@350..351 - PathSegment@350..351 - Ident@350..351 "S" - Gt@351..352 ">" + GenericArgList@349..352 + Lt@349..350 "<" + TypeGenericArg@350..351 + PathType@350..351 + Path@350..351 + PathSegment@350..351 + Ident@350..351 "S" + Gt@351..352 ">" RParen@352..353 ")" Newline@353..354 "\n" RBrace@354..355 "}" @@ -319,17 +319,17 @@ Root@0..652 Gt@363..364 ">" WhiteSpace@364..365 " " PathType@365..374 - Path@365..371 - PathSegment@365..371 + Path@365..374 + PathSegment@365..374 Ident@365..371 "Parser" - GenericArgList@371..374 - Lt@371..372 "<" - TypeGenericArg@372..373 - PathType@372..373 - Path@372..373 - PathSegment@372..373 - Ident@372..373 "S" - Gt@373..374 ">" + GenericArgList@371..374 + Lt@371..372 "<" + TypeGenericArg@372..373 + PathType@372..373 + Path@372..373 + PathSegment@372..373 + Ident@372..373 "S" + Gt@373..374 ">" WhiteSpace@374..375 " " Newline@375..376 "\n" WhiteSpace@376..380 " " @@ -407,17 +407,17 @@ Root@0..652 Colon@472..473 ":" WhiteSpace@473..474 " " PathType@474..492 - Path@474..480 - PathSegment@474..480 + Path@474..492 + PathSegment@474..492 Ident@474..480 "Option" - GenericArgList@480..492 - Lt@480..481 "<" - TypeGenericArg@481..491 - PathType@481..491 - Path@481..491 - PathSegment@481..491 - Ident@481..491 "Checkpoint" - Gt@491..492 ">" + GenericArgList@480..492 + Lt@480..481 "<" + TypeGenericArg@481..491 + PathType@481..491 + Path@481..491 + PathSegment@481..491 + Ident@481..491 "Checkpoint" + Gt@491..492 ">" RParen@492..493 ")" WhiteSpace@493..494 " " Arrow@494..496 "->" @@ -508,17 +508,17 @@ Root@0..652 Plus@624..625 "+" WhiteSpace@625..626 " " TraitRef@626..632 - Path@626..629 - PathSegment@626..629 + Path@626..632 + PathSegment@626..632 Ident@626..629 "Add" - GenericArgList@629..632 - Lt@629..630 "<" - TypeGenericArg@630..631 - PathType@630..631 - Path@630..631 - PathSegment@630..631 - Ident@630..631 "T" - Gt@631..632 ">" + GenericArgList@629..632 + Lt@629..630 "<" + TypeGenericArg@630..631 + PathType@630..631 + Path@630..631 + PathSegment@630..631 + Ident@630..631 "T" + Gt@631..632 ">" WhiteSpace@632..633 " " Newline@633..634 "\n" WhereClause@634..649 @@ -534,17 +534,17 @@ Root@0..652 WhiteSpace@642..643 " " TypeBound@643..649 TraitRef@643..649 - Path@643..646 - PathSegment@643..646 + Path@643..649 + PathSegment@643..649 Ident@643..646 "Add" - GenericArgList@646..649 - Lt@646..647 "<" - TypeGenericArg@647..648 - PathType@647..648 - Path@647..648 - PathSegment@647..648 - Ident@647..648 "T" - Gt@648..649 ">" + GenericArgList@646..649 + Lt@646..647 "<" + TypeGenericArg@647..648 + PathType@647..648 + Path@647..648 + PathSegment@647..648 + Ident@647..648 "T" + Gt@648..649 ">" Newline@649..650 "\n" TraitItemList@650..652 LBrace@650..651 "{" diff --git a/crates/parser2/test_files/syntax_node/items/type.snap b/crates/parser2/test_files/syntax_node/items/type.snap index d3a347df8..b93344028 100644 --- a/crates/parser2/test_files/syntax_node/items/type.snap +++ b/crates/parser2/test_files/syntax_node/items/type.snap @@ -36,22 +36,22 @@ Root@0..54 Eq@36..37 "=" WhiteSpace@37..38 " " PathType@38..54 - Path@38..44 - PathSegment@38..44 + Path@38..54 + PathSegment@38..54 Ident@38..44 "Result" - GenericArgList@44..54 - Lt@44..45 "<" - TypeGenericArg@45..46 - PathType@45..46 - Path@45..46 - PathSegment@45..46 - Ident@45..46 "T" - Comma@46..47 "," - WhiteSpace@47..48 " " - TypeGenericArg@48..53 - PathType@48..53 - Path@48..53 - PathSegment@48..53 - Ident@48..53 "Error" - Gt@53..54 ">" + GenericArgList@44..54 + Lt@44..45 "<" + TypeGenericArg@45..46 + PathType@45..46 + Path@45..46 + PathSegment@45..46 + Ident@45..46 "T" + Comma@46..47 "," + WhiteSpace@47..48 " " + TypeGenericArg@48..53 + PathType@48..53 + Path@48..53 + PathSegment@48..53 + Ident@48..53 "Error" + Gt@53..54 ">" diff --git a/crates/parser2/test_files/syntax_node/structs/generics.snap b/crates/parser2/test_files/syntax_node/structs/generics.snap index 6debda1ee..ae26fa650 100644 --- a/crates/parser2/test_files/syntax_node/structs/generics.snap +++ b/crates/parser2/test_files/syntax_node/structs/generics.snap @@ -244,17 +244,17 @@ Root@0..563 WhiteSpace@317..321 " " WherePredicate@321..347 PathType@321..330 - Path@321..327 - PathSegment@321..327 + Path@321..330 + PathSegment@321..330 Ident@321..327 "Option" - GenericArgList@327..330 - Lt@327..328 "<" - TypeGenericArg@328..329 - PathType@328..329 - Path@328..329 - PathSegment@328..329 - Ident@328..329 "T" - Gt@329..330 ">" + GenericArgList@327..330 + Lt@327..328 "<" + TypeGenericArg@328..329 + PathType@328..329 + Path@328..329 + PathSegment@328..329 + Ident@328..329 "T" + Gt@329..330 ">" TypeBoundList@330..347 Colon@330..331 ":" WhiteSpace@331..332 " " @@ -276,17 +276,17 @@ Root@0..563 WhiteSpace@349..353 " " WherePredicate@353..379 PathType@353..362 - Path@353..359 - PathSegment@353..359 + Path@353..362 + PathSegment@353..362 Ident@353..359 "Result" - GenericArgList@359..362 - Lt@359..360 "<" - TypeGenericArg@360..361 - PathType@360..361 - Path@360..361 - PathSegment@360..361 - Ident@360..361 "U" - Gt@361..362 ">" + GenericArgList@359..362 + Lt@359..360 "<" + TypeGenericArg@360..361 + PathType@360..361 + Path@360..361 + PathSegment@360..361 + Ident@360..361 "U" + Gt@361..362 ">" TypeBoundList@362..379 Colon@362..363 ":" WhiteSpace@363..364 " " @@ -419,24 +419,24 @@ Root@0..563 WhiteSpace@503..504 " " TypeBound@504..517 TraitRef@504..517 - Path@504..509 - PathSegment@504..509 + Path@504..517 + PathSegment@504..517 Ident@504..509 "Trait" - GenericArgList@509..517 - Lt@509..510 "<" - TypeGenericArg@510..513 - PathType@510..513 - Path@510..513 - PathSegment@510..513 - Ident@510..513 "i32" - Comma@513..514 "," - WhiteSpace@514..515 " " - TypeGenericArg@515..516 - PathType@515..516 - Path@515..516 - PathSegment@515..516 - Ident@515..516 "Y" - Gt@516..517 ">" + GenericArgList@509..517 + Lt@509..510 "<" + TypeGenericArg@510..513 + PathType@510..513 + Path@510..513 + PathSegment@510..513 + Ident@510..513 "i32" + Comma@513..514 "," + WhiteSpace@514..515 " " + TypeGenericArg@515..516 + PathType@515..516 + Path@515..516 + PathSegment@515..516 + Ident@515..516 "Y" + Gt@516..517 ">" Newline@517..518 "\n" RecordFieldDefList@518..563 LBrace@518..519 "{" diff --git a/docs/validate_doc_examples.py b/docs/validate_doc_examples.py index 9c450a41b..fb1d08256 100755 --- a/docs/validate_doc_examples.py +++ b/docs/validate_doc_examples.py @@ -17,17 +17,17 @@ class CodeSnippet(NamedTuple): path: pathlib.Path - index: int + idx: int content: str def append_content(self, line: str) -> 'CodeSnippet': - return CodeSnippet(path=self.path, index=self.index, content=self.content + line) + return CodeSnippet(path=self.path, idx=self.idx, content=self.content + line) def get_snippet_hash(self) -> str: return hashlib.sha1(self.content.encode('utf-8')).hexdigest() def unique_name(self) -> str: - return f"{self.path.name}_{self.index}.fe" + return f"{self.path.name}_{self.idx}.fe" def get_all_doc_files() -> Iterable[pathlib.Path]: for path in BOOK_SRC_DIR.rglob('*.md'): @@ -43,7 +43,7 @@ def get_all_snippets_in_file(path: pathlib.Path) -> Iterable[CodeSnippet]: snippet_index = 0 for line in lines: if 'ignore' not in line and line.strip().startswith(CODE_SNIPPET_START_MARKER): - snippet = CodeSnippet(path=path, index=snippet_index, content='') + snippet = CodeSnippet(path=path, idx=snippet_index, content='') snippet_index += 1 elif line.strip().startswith(CODE_SNIPPET_END_MARKER): if snippet != None: