Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix the bug of next_point in source_map #103185

Merged
merged 2 commits into from
Oct 20, 2022

Conversation

chenyukang
Copy link
Member

@chenyukang chenyukang commented Oct 18, 2022

There is a bug in next_point, the new span won't move to next position when be called in the first time.

For this reason, our current code is working like this:

  1. When we really want to move to the next position, we called two times of next_point
  2. Some code which use next_point actually done the same thing with shrink_to_hi

This fix make sure when next_point is called, span will move with the width at least 1, and also work correctly in the scenario of multiple bytes.

Ref: #103140 (comment)

r? @davidtwco

@rustbot rustbot added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Oct 18, 2022
@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Oct 18, 2022
@chenyukang chenyukang force-pushed the yukang/fix-span-next-point branch from 1cb5780 to 0af255a Compare October 18, 2022 12:18
@davidtwco
Copy link
Member

@bors r+

@bors
Copy link
Contributor

bors commented Oct 18, 2022

📌 Commit 0af255a has been approved by davidtwco

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Oct 18, 2022
Comment on lines 864 to 868
// If the width is 1, then the next span should point to the same `lo` and `hi`. However,
// in the case of a multibyte character, where the width != 1, the next span should
// span multiple bytes to include the whole character.
let end_of_next_point =
start_of_next_point.checked_add(width - 1).unwrap_or(start_of_next_point);
start_of_next_point.checked_add(width).unwrap_or(start_of_next_point);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've always found this bit confusing, but I'm wondering if this comment is now out-of-date?

The next_point() function used to return an empty span (when the "width is 1" as in the comment) pointing just before the next character. This change seems to change it so that it is a non-empty span containing the next character.

I'm also wondering if the name of the function is also a bit misleading? The original next_point function always returned an empty span (a "point", not a region). This was changed in #47420 to have the somewhat confusing behavior where an empty span would move forward to span the next character (non-empty), and a non-empty span would return an empty span pointing just past the end. It's not clear from that PR why that behavior was chosen.

I also think this function is still somewhat buggy with respect to multi-byte characters. Below is a unittest which illustrates some oddities. Perhaps it might be good to add this unittest?

#[test]
fn next_point() {
    let sm = SourceMap::new(FilePathMapping::empty());
    sm.new_source_file(PathBuf::from("example.rs").into(), "a…b".to_string());
    let span = Span::with_root_ctxt(BytePos(0), BytePos(0));
    // This confusingly does not advance the span?
    let span = sm.next_point(span);
    assert_eq!(span.lo().0, 0);
    assert_eq!(span.hi().0, 0); // ERROR: This should probably be 1?

    let span = Span::with_root_ctxt(BytePos(0), BytePos(1));
    let span = sm.next_point(span);
    assert_eq!(span.lo().0, 1);
    assert_eq!(span.hi().0, 4);

    // This creates an invalid span, slicing in the middle of a multi-byte char?
    let span = Span::with_root_ctxt(BytePos(1), BytePos(1));
    let span = sm.next_point(span);
    assert_eq!(span.lo().0, 1);
    assert_eq!(span.hi().0, 2); // ERROR: This should probably be 4?

    let span = Span::with_root_ctxt(BytePos(1), BytePos(4));
    let span = sm.next_point(span);
    assert_eq!(span.lo().0, 4);
    assert_eq!(span.hi().0, 5);
    // This creates an invalid span, pointing past the end of the file?
    let span = sm.next_point(span);
    assert_eq!(span.lo().0, 5);
    assert_eq!(span.hi().0, 6); // ERROR: This should probably be 5?

    // Empty span pointing just past the last byte.
    let span = Span::with_root_ctxt(BytePos(5), BytePos(5));
    let span = sm.next_point(span);
    assert_eq!(span.lo().0, 5);
    assert_eq!(span.hi().0, 6); // ERROR: This should probably be 5?
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This unit test implied another issue:

// This creates an invalid span, slicing in the middle of a multi-byte char?
    let span = Span::with_root_ctxt(BytePos(1), BytePos(1));
    let span = sm.next_point(span);
    assert_eq!(span.lo().0, 1);
    assert_eq!(span.hi().0, 2);

When lo and hi are same, we just reutrn the width with 1:

if sp.lo == sp.hi {

So the result is span.hi().0 will be 2.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @ehuss,

I fixed all other issues in the test cases, except for this one:

 let span = sm.next_point(span);
    assert_eq!(span.lo().0, 0);
    assert_eq!(span.hi().0, 0); // ERROR: This should probably be 1?

It return the same span because it's a dummy span, something special for macros..

matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Oct 18, 2022
…int, r=davidtwco

Fix the bug of next_point in source_map

There is a bug in `next_point`, the new span won't move to next position when be called in the first time.

For this reason, our current code is working like this:
1. When we really want to move to the next position, we called two times of `next_point`
2. Some code which use `next_point` actually done the same thing with `shrink_to_hi`

This fix make sure when `next_point` is called, span will move with the width at least 1, and also work correctly in the scenario of multiple bytes.

Ref: rust-lang#103140 (comment)

r? `@davidtwco`
@matthiaskrgr
Copy link
Member

@bors rollup=iffy might cause some clippy output change?
#103207 (comment)

@rustbot
Copy link
Collaborator

rustbot commented Oct 19, 2022

Some changes occurred in src/tools/clippy

cc @rust-lang/clippy

@rust-log-analyzer

This comment has been minimized.

@chenyukang chenyukang force-pushed the yukang/fix-span-next-point branch from 663a55f to e84cdb8 Compare October 19, 2022 03:48
@rust-log-analyzer

This comment has been minimized.

@chenyukang
Copy link
Member Author

@bors rollup=iffy might cause some clippy output change? #103207 (comment)

Fixed by:

- let hi = cx.sess().source_map().next_point(remove_span).hi();
- let fmpos = cx.sess().source_map().lookup_byte_offset(hi);
+ let fmpos = cx.sess().source_map().lookup_byte_offset(remove_span.hi());

r? @davidtwco

@chenyukang chenyukang force-pushed the yukang/fix-span-next-point branch from d35bd9d to 249b1d5 Compare October 19, 2022 06:24
@davidtwco
Copy link
Member

@bors r-

@bors bors added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Oct 19, 2022
@davidtwco
Copy link
Member

Please avoid pushing to the pull request after it has been approved, or ping someone to unapprove it if you have to, otherwise it can get merged with only the earlier changes.

@davidtwco
Copy link
Member

@bors r+

@bors
Copy link
Contributor

bors commented Oct 19, 2022

📌 Commit 249b1d54a8c1c3238cb131433642a34dcc24ef39 has been approved by davidtwco

It is now in the queue for this repository.

@bors bors removed the S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. label Oct 19, 2022
@bors bors added the S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. label Oct 19, 2022
Copy link
Contributor

@ehuss ehuss left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, FWIW, there is a dedicated test file for SourceMap in rustc_span/src/source_map/tests.rs, might be better to put this test there since it is primarily for SourceMap.

compiler/rustc_span/src/tests.rs Outdated Show resolved Hide resolved
compiler/rustc_span/src/tests.rs Outdated Show resolved Hide resolved
compiler/rustc_span/src/tests.rs Outdated Show resolved Hide resolved
@davidtwco
Copy link
Member

@bors r-

@bors bors added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Oct 19, 2022
@chenyukang chenyukang force-pushed the yukang/fix-span-next-point branch from 249b1d5 to eb8aa97 Compare October 19, 2022 13:08
@chenyukang
Copy link
Member Author

r? @davidtwco

@davidtwco
Copy link
Member

@bors r+

@bors
Copy link
Contributor

bors commented Oct 20, 2022

📌 Commit eb8aa97 has been approved by davidtwco

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Oct 20, 2022
@bors
Copy link
Contributor

bors commented Oct 20, 2022

⌛ Testing commit eb8aa97 with merge 53728ff...

@bors
Copy link
Contributor

bors commented Oct 20, 2022

☀️ Test successful - checks-actions
Approved by: davidtwco
Pushing 53728ff to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label Oct 20, 2022
@bors bors merged commit 53728ff into rust-lang:master Oct 20, 2022
@rustbot rustbot added this to the 1.66.0 milestone Oct 20, 2022
@rust-timer
Copy link
Collaborator

Finished benchmarking commit (53728ff): comparison URL.

Overall result: no relevant changes - no action needed

@rustbot label: -perf-regression

Instruction count

This benchmark run did not return any relevant results for this metric.

Max RSS (memory usage)

Results

This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.

mean1 range count2
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
2.8% [2.8%, 2.8%] 1
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) - - 0

Cycles

This benchmark run did not return any relevant results for this metric.

Footnotes

  1. the arithmetic mean of the percent change

  2. number of relevant changes

@jruderman
Copy link
Contributor

This may have introduced a compiler hang: #103451

Aaron1011 pushed a commit to Aaron1011/rust that referenced this pull request Jan 6, 2023
…t, r=davidtwco

Fix the bug of next_point in source_map

There is a bug in `next_point`, the new span won't move to next position when be called in the first time.

For this reason, our current code is working like this:
1. When we really want to move to the next position, we called two times of `next_point`
2. Some code which use `next_point` actually done the same thing with `shrink_to_hi`

This fix make sure when `next_point` is called, span will move with the width at least 1, and also work correctly in the scenario of multiple bytes.

Ref: rust-lang#103140 (comment)

r? `@davidtwco`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
merged-by-bors This PR was explicitly merged by bors. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.