|
5 | 5 | use annotate_snippets::{AnnotationKind, Group, Level, Origin, Padding, Patch, Renderer, Snippet};
|
6 | 6 |
|
7 | 7 | use annotate_snippets::renderer::OutputTheme;
|
8 |
| -use snapbox::{assert_data_eq, str}; |
| 8 | +use snapbox::{assert_data_eq, str, IntoData}; |
9 | 9 |
|
10 | 10 | #[test]
|
11 | 11 | fn ends_on_col0() {
|
@@ -3445,3 +3445,248 @@ LL | let _: S::<bool>::Pr = ();
|
3445 | 3445 | let renderer = Renderer::plain().anonymized_line_numbers(true);
|
3446 | 3446 | assert_data_eq!(renderer.render(input), expected);
|
3447 | 3447 | }
|
| 3448 | + |
| 3449 | +#[test] |
| 3450 | +fn unsafe_extern_suggestion() { |
| 3451 | + // tests/ui/rust-2024/unsafe-extern-blocks/unsafe-extern-suggestion.rs |
| 3452 | + |
| 3453 | + let source = r#"//@ run-rustfix |
| 3454 | +
|
| 3455 | +#![deny(missing_unsafe_on_extern)] |
| 3456 | +#![allow(unused)] |
| 3457 | +
|
| 3458 | +extern "C" { |
| 3459 | + //~^ ERROR extern blocks should be unsafe [missing_unsafe_on_extern] |
| 3460 | + //~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2024! |
| 3461 | + static TEST1: i32; |
| 3462 | + fn test1(i: i32); |
| 3463 | +} |
| 3464 | +
|
| 3465 | +unsafe extern "C" { |
| 3466 | + static TEST2: i32; |
| 3467 | + fn test2(i: i32); |
| 3468 | +} |
| 3469 | +
|
| 3470 | +fn main() {} |
| 3471 | +"#; |
| 3472 | + |
| 3473 | + let title_0 = |
| 3474 | + "this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2024!"; |
| 3475 | + let title_1 = "for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/unsafe-extern.html>"; |
| 3476 | + |
| 3477 | + let input = &[ |
| 3478 | + Group::with_title(Level::ERROR.title("extern blocks should be unsafe")) |
| 3479 | + .element( |
| 3480 | + Snippet::source(source) |
| 3481 | + .path("$DIR/unsafe-extern-suggestion.rs") |
| 3482 | + .annotation( |
| 3483 | + AnnotationKind::Context |
| 3484 | + .span(71..71) |
| 3485 | + .label("help: needs `unsafe` before the extern keyword: `unsafe`"), |
| 3486 | + ) |
| 3487 | + .annotation(AnnotationKind::Primary.span(71..303)), |
| 3488 | + ) |
| 3489 | + .element(Level::WARNING.message(title_0)) |
| 3490 | + .element(Level::NOTE.message(title_1)), |
| 3491 | + Group::with_title(Level::NOTE.title("the lint level is defined here")).element( |
| 3492 | + Snippet::source(source) |
| 3493 | + .path("$DIR/unsafe-extern-suggestion.rs") |
| 3494 | + .annotation(AnnotationKind::Primary.span(25..49)), |
| 3495 | + ), |
| 3496 | + ]; |
| 3497 | + |
| 3498 | + let expected = str![[r#" |
| 3499 | +error: extern blocks should be unsafe |
| 3500 | + --> $DIR/unsafe-extern-suggestion.rs:6:1 |
| 3501 | + | |
| 3502 | +LL | extern "C" { |
| 3503 | + | ^ |
| 3504 | + | | |
| 3505 | + | _help: needs `unsafe` before the extern keyword: `unsafe` |
| 3506 | + | | |
| 3507 | +LL | | //~^ ERROR extern blocks should be unsafe [missing_unsafe_on_extern] |
| 3508 | +LL | | //~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2024! |
| 3509 | +LL | | static TEST1: i32; |
| 3510 | +LL | | fn test1(i: i32); |
| 3511 | +LL | | } |
| 3512 | + | |_^ |
| 3513 | + | |
| 3514 | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2024! |
| 3515 | + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/unsafe-extern.html> |
| 3516 | +note: the lint level is defined here |
| 3517 | + --> $DIR/unsafe-extern-suggestion.rs:3:9 |
| 3518 | + | |
| 3519 | +LL | #![deny(missing_unsafe_on_extern)] |
| 3520 | + | ^^^^^^^^^^^^^^^^^^^^^^^^ |
| 3521 | +"#]]; |
| 3522 | + let renderer = Renderer::plain().anonymized_line_numbers(true); |
| 3523 | + assert_data_eq!(renderer.render(input), expected); |
| 3524 | +} |
| 3525 | + |
| 3526 | +#[test] |
| 3527 | +fn alloc_error_handler_bad_signature_2() { |
| 3528 | + // tests/ui/alloc-error/alloc-error-handler-bad-signature-2.rs |
| 3529 | + |
| 3530 | + let source = r#"//@ compile-flags:-C panic=abort |
| 3531 | +
|
| 3532 | +#![feature(alloc_error_handler)] |
| 3533 | +#![no_std] |
| 3534 | +#![no_main] |
| 3535 | +
|
| 3536 | +struct Layout; |
| 3537 | +
|
| 3538 | +#[alloc_error_handler] |
| 3539 | +fn oom( |
| 3540 | + info: Layout, //~^ ERROR mismatched types |
| 3541 | +) { //~^^ ERROR mismatched types |
| 3542 | + loop {} |
| 3543 | +} |
| 3544 | +
|
| 3545 | +#[panic_handler] |
| 3546 | +fn panic(_: &core::panic::PanicInfo) -> ! { loop {} } |
| 3547 | +"#; |
| 3548 | + let title_0 = |
| 3549 | + "`core::alloc::Layout` and `Layout` have similar names, but are actually distinct types"; |
| 3550 | + |
| 3551 | + let input = &[ |
| 3552 | + Group::with_title(Level::ERROR.title("mismatched types").id("E0308")) |
| 3553 | + .element( |
| 3554 | + Snippet::source(source) |
| 3555 | + .path("$DIR/alloc-error-handler-bad-signature-2.rs") |
| 3556 | + .annotation( |
| 3557 | + AnnotationKind::Primary |
| 3558 | + .span(130..230) |
| 3559 | + .label("expected `Layout`, found `core::alloc::Layout`"), |
| 3560 | + ) |
| 3561 | + .annotation( |
| 3562 | + AnnotationKind::Context |
| 3563 | + .span(130..185) |
| 3564 | + .label("arguments to this function are incorrect"), |
| 3565 | + ) |
| 3566 | + .annotation( |
| 3567 | + AnnotationKind::Context |
| 3568 | + .span(107..129) |
| 3569 | + .label("in this procedural macro expansion"), |
| 3570 | + ), |
| 3571 | + ) |
| 3572 | + .element(Level::NOTE.message(title_0)), |
| 3573 | + Group::with_title(Level::NOTE.title("`core::alloc::Layout` is defined in crate `core`")) |
| 3574 | + .element( |
| 3575 | + Origin::path("$SRC_DIR/core/src/alloc/layout.rs") |
| 3576 | + .line(40) |
| 3577 | + .char_column(0) |
| 3578 | + .primary(true), |
| 3579 | + ), |
| 3580 | + Group::with_title(Level::NOTE.title("`Layout` is defined in the current crate")).element( |
| 3581 | + Snippet::source(source) |
| 3582 | + .path("$DIR/alloc-error-handler-bad-signature-2.rs") |
| 3583 | + .annotation(AnnotationKind::Primary.span(91..104)), |
| 3584 | + ), |
| 3585 | + Group::with_title(Level::NOTE.title("function defined here")).element( |
| 3586 | + Snippet::source(source) |
| 3587 | + .path("$DIR/alloc-error-handler-bad-signature-2.rs") |
| 3588 | + .annotation(AnnotationKind::Context.span(142..154).label("")) |
| 3589 | + .annotation(AnnotationKind::Primary.span(133..136)), |
| 3590 | + ), |
| 3591 | + ]; |
| 3592 | + let expected = str![[r#" |
| 3593 | +error[E0308]: mismatched types |
| 3594 | + --> $DIR/alloc-error-handler-bad-signature-2.rs:10:1 |
| 3595 | + | |
| 3596 | +LL | #[alloc_error_handler] |
| 3597 | + | ---------------------- in this procedural macro expansion |
| 3598 | +LL | // fn oom( |
| 3599 | +LL | || info: Layout, //~^ ERROR mismatched types |
| 3600 | +LL | || ) { //~^^ ERROR mismatched types |
| 3601 | + | ||_- arguments to this function are incorrect |
| 3602 | +LL | | loop {} |
| 3603 | +LL | | } |
| 3604 | + | |__^ expected `Layout`, found `core::alloc::Layout` |
| 3605 | + | |
| 3606 | + = note: `core::alloc::Layout` and `Layout` have similar names, but are actually distinct types |
| 3607 | +note: `core::alloc::Layout` is defined in crate `core` |
| 3608 | + --> $SRC_DIR/core/src/alloc/layout.rs:40:0 |
| 3609 | +note: `Layout` is defined in the current crate |
| 3610 | + --> $DIR/alloc-error-handler-bad-signature-2.rs:7:1 |
| 3611 | + | |
| 3612 | +LL | struct Layout; |
| 3613 | + | ^^^^^^^^^^^^^ |
| 3614 | +note: function defined here |
| 3615 | + --> $DIR/alloc-error-handler-bad-signature-2.rs:10:4 |
| 3616 | + | |
| 3617 | +LL | fn oom( |
| 3618 | + | ^^^ |
| 3619 | +LL | info: Layout, //~^ ERROR mismatched types |
| 3620 | + | ------------ |
| 3621 | +"#]]; |
| 3622 | + let renderer = Renderer::plain().anonymized_line_numbers(true); |
| 3623 | + assert_data_eq!(renderer.render(input), expected); |
| 3624 | +} |
| 3625 | + |
| 3626 | +#[test] |
| 3627 | +fn str_escape() { |
| 3628 | + // tests/ui/str/str-escape.rs |
| 3629 | + |
| 3630 | + let source = r#"//@ check-pass |
| 3631 | +// ignore-tidy-tab |
| 3632 | +//@ edition: 2021 |
| 3633 | +
|
| 3634 | +fn main() { |
| 3635 | + let s = "\ |
| 3636 | +
|
| 3637 | + "; |
| 3638 | + //~^^^ WARNING multiple lines skipped by escaped newline |
| 3639 | + assert_eq!(s, ""); |
| 3640 | +
|
| 3641 | + let s = c"foo\ |
| 3642 | + bar |
| 3643 | + "; |
| 3644 | + //~^^^ WARNING whitespace symbol '\u{a0}' is not skipped |
| 3645 | + assert_eq!(s, c"foo bar\n "); |
| 3646 | +
|
| 3647 | + let s = "a\ |
| 3648 | + b"; |
| 3649 | + assert_eq!(s, "ab"); |
| 3650 | +
|
| 3651 | + let s = "a\ |
| 3652 | + b"; |
| 3653 | + assert_eq!(s, "ab"); |
| 3654 | +
|
| 3655 | + let s = b"a\ |
| 3656 | + |
| 3657 | + b"; |
| 3658 | + //~^^ WARNING whitespace symbol '\u{c}' is not skipped |
| 3659 | + // '\x0c' is ASCII whitespace, but it may not need skipped |
| 3660 | + // discussion: https://github.com/rust-lang/rust/pull/108403 |
| 3661 | + assert_eq!(s, b"a\x0cb"); |
| 3662 | +} |
| 3663 | +"#; |
| 3664 | + |
| 3665 | + let input = |
| 3666 | + &[ |
| 3667 | + Group::with_title(Level::WARNING.title(r#"whitespace symbol '\u{a0}' is not skipped"#)) |
| 3668 | + .element( |
| 3669 | + Snippet::source(source) |
| 3670 | + .path("$DIR/str-escape.rs") |
| 3671 | + .annotation( |
| 3672 | + AnnotationKind::Context |
| 3673 | + .span(203..205) |
| 3674 | + .label(r#"whitespace symbol '\u{a0}' is not skipped"#), |
| 3675 | + ) |
| 3676 | + .annotation(AnnotationKind::Primary.span(199..205)), |
| 3677 | + ), |
| 3678 | + ]; |
| 3679 | + let expected = str![[r#" |
| 3680 | +warning: whitespace symbol '\u{a0}' is not skipped |
| 3681 | + --> $DIR/str-escape.rs:12:18 |
| 3682 | + | |
| 3683 | +LL | let s = c"foo\ |
| 3684 | + | __________________^ |
| 3685 | +LL | | bar |
| 3686 | + | | ^ whitespace symbol '\u{a0}' is not skipped |
| 3687 | + | |___| |
| 3688 | + | |
| 3689 | +"#]]; |
| 3690 | + let renderer = Renderer::plain().anonymized_line_numbers(true); |
| 3691 | + assert_data_eq!(renderer.render(input), expected.raw()); |
| 3692 | +} |
0 commit comments