diff --git a/.noir-sync-commit b/.noir-sync-commit index c29458064f4..e426436db9b 100644 --- a/.noir-sync-commit +++ b/.noir-sync-commit @@ -1 +1 @@ -1fabcde195f3965c6b8701eb4e1fed49ec1bde4b +a213c15275892581e5d8f7235baf08a6cb137da4 diff --git a/noir/noir-repo/noir_stdlib/src/embedded_curve_ops.nr b/noir/noir-repo/noir_stdlib/src/embedded_curve_ops.nr index 6b70b6ddef0..9324802c2f8 100644 --- a/noir/noir-repo/noir_stdlib/src/embedded_curve_ops.nr +++ b/noir/noir-repo/noir_stdlib/src/embedded_curve_ops.nr @@ -105,6 +105,9 @@ fn multi_scalar_mul_array_return(points: [EmbeddedCurvePoint; N], sc #[foreign(multi_scalar_mul)] pub(crate) fn multi_scalar_mul_slice(points: [EmbeddedCurvePoint], scalars: [EmbeddedCurveScalar]) -> [Field; 3] {} +#[foreign(multi_scalar_mul)] +pub(crate) fn multi_scalar_mul_slice(points: [EmbeddedCurvePoint], scalars: [EmbeddedCurveScalar]) -> [Field; 3] {} + // docs:start:fixed_base_scalar_mul pub fn fixed_base_scalar_mul(scalar: EmbeddedCurveScalar) -> EmbeddedCurvePoint // docs:end:fixed_base_scalar_mul diff --git a/noir/noir-repo/noir_stdlib/src/hash/mod.nr b/noir/noir-repo/noir_stdlib/src/hash/mod.nr index fb81f624d38..69470b56ab2 100644 --- a/noir/noir-repo/noir_stdlib/src/hash/mod.nr +++ b/noir/noir-repo/noir_stdlib/src/hash/mod.nr @@ -34,15 +34,7 @@ pub fn pedersen_commitment(input: [Field; N]) -> EmbeddedCurvePoint } fn pedersen_commitment_with_separator(input: [Field; N], separator: u32) -> EmbeddedCurvePoint { - let value = __pedersen_commitment_with_separator(input, separator); - if (value[0] == 0) & (value[1] == 0) { - EmbeddedCurvePoint { x: 0, y: 0, is_infinite: true } - } else { - EmbeddedCurvePoint { x: value[0], y: value[1], is_infinite: false } - } -} - -fn pedersen_commitment_with_separator_noir(input: [Field; N], separator: u32) -> EmbeddedCurvePoint {let mut points = [EmbeddedCurveScalar { lo: 0, hi: 0 }; N]; + let mut points = [EmbeddedCurveScalar { lo: 0, hi: 0 }; N]; for i in 0..N { // we use the unsafe version because the multi_scalar_mul will constraint the scalars. points[i] = from_field_unsafe(input[i]); diff --git a/noir/noir-repo/tooling/lsp/src/requests/inlay_hint.rs b/noir/noir-repo/tooling/lsp/src/requests/inlay_hint.rs index 2d8830d877f..c47e59b0c2b 100644 --- a/noir/noir-repo/tooling/lsp/src/requests/inlay_hint.rs +++ b/noir/noir-repo/tooling/lsp/src/requests/inlay_hint.rs @@ -1,3 +1,4 @@ +use fm::codespan_files::Files; use std::future::{self, Future}; use async_lsp::ResponseError; @@ -39,23 +40,7 @@ pub(crate) fn on_inlay_hint_request( let source = file.source(); let (parsed_moduled, _errors) = noirc_frontend::parse_program(source); - // The version of codespan_lsp is pretty old and relies on an old version of lsp-types. - // We can't downgrade because we need some types from the latest version, and there's - // no newer version of codespan_lsp... but we just need this type here, so we create - // a copy of a Range to get an older type. - let range = lsp_types_0_88_0::Range { - start: lsp_types_0_88_0::Position { - line: params.range.start.line, - character: params.range.start.character, - }, - end: lsp_types_0_88_0::Position { - line: params.range.end.line, - character: params.range.end.character, - }, - }; - - let span = codespan_lsp::range_to_byte_span(args.files, file_id, &range) - .ok() + let span = range_to_byte_span(args.files, file_id, ¶ms.range) .map(|range| Span::from(range.start as u32..range.end as u32)); let mut collector = InlayHintCollector::new(args.files, file_id, args.interner, span); @@ -596,4 +581,67 @@ mod inlay_hints_tests { panic!("Expected InlayHintLabel::LabelParts, got {:?}", inlay_hint.label); } } + + #[test] + async fn test_do_not_panic_when_given_line_is_too_big() { + let inlay_hints = get_inlay_hints(0, 100000).await; + assert!(!inlay_hints.is_empty()); + } +} + +// These functions are copied from the codespan_lsp crate, except that they never panic +// (the library will sometimes panic, so functions returning Result are not always accurate) + +fn range_to_byte_span( + files: &FileMap, + file_id: FileId, + range: &lsp_types::Range, +) -> Option> { + Some( + position_to_byte_index(files, file_id, &range.start)? + ..position_to_byte_index(files, file_id, &range.end)?, + ) +} + +fn position_to_byte_index( + files: &FileMap, + file_id: FileId, + position: &lsp_types::Position, +) -> Option { + let Ok(source) = files.source(file_id) else { + return None; + }; + + let Ok(line_span) = files.line_range(file_id, position.line as usize) else { + return None; + }; + let line_str = source.get(line_span.clone())?; + + let byte_offset = character_to_line_offset(line_str, position.character)?; + + Some(line_span.start + byte_offset) +} + +fn character_to_line_offset(line: &str, character: u32) -> Option { + let line_len = line.len(); + let mut character_offset = 0; + + let mut chars = line.chars(); + while let Some(ch) = chars.next() { + if character_offset == character { + let chars_off = chars.as_str().len(); + let ch_off = ch.len_utf8(); + + return Some(line_len - chars_off - ch_off); + } + + character_offset += ch.len_utf16() as u32; + } + + // Handle positions after the last character on the line + if character_offset == character { + Some(line_len) + } else { + None + } }