summaryrefslogtreecommitdiffstats
path: root/src/tools/clippy/tests/ui/needless_question_mark.fixed
blob: ba9d15e59d0e45376374c23b07b87c661def3a17 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
// run-rustfix

#![warn(clippy::needless_question_mark)]
#![allow(
    clippy::needless_return,
    clippy::unnecessary_unwrap,
    clippy::upper_case_acronyms,
    dead_code,
    unused_must_use
)]
#![feature(custom_inner_attributes)]

struct TO {
    magic: Option<usize>,
}

struct TR {
    magic: Result<usize, bool>,
}

fn simple_option_bad1(to: TO) -> Option<usize> {
    // return as a statement
    return to.magic;
}

// formatting will add a semi-colon, which would make
// this identical to the test case above
#[rustfmt::skip]
fn simple_option_bad2(to: TO) -> Option<usize> {
    // return as an expression
    return to.magic
}

fn simple_option_bad3(to: TO) -> Option<usize> {
    // block value "return"
    to.magic
}

fn simple_option_bad4(to: Option<TO>) -> Option<usize> {
    // single line closure
    to.and_then(|t| t.magic)
}

// formatting this will remove the block brackets, making
// this test identical to the one above
#[rustfmt::skip]
fn simple_option_bad5(to: Option<TO>) -> Option<usize> {
    // closure with body
    to.and_then(|t| {
        t.magic
    })
}

fn simple_result_bad1(tr: TR) -> Result<usize, bool> {
    return tr.magic;
}

// formatting will add a semi-colon, which would make
// this identical to the test case above
#[rustfmt::skip]
fn simple_result_bad2(tr: TR) -> Result<usize, bool> {
    return tr.magic
}

fn simple_result_bad3(tr: TR) -> Result<usize, bool> {
    tr.magic
}

fn simple_result_bad4(tr: Result<TR, bool>) -> Result<usize, bool> {
    tr.and_then(|t| t.magic)
}

// formatting this will remove the block brackets, making
// this test identical to the one above
#[rustfmt::skip]
fn simple_result_bad5(tr: Result<TR, bool>) -> Result<usize, bool> {
    tr.and_then(|t| {
        t.magic
    })
}

fn also_bad(tr: Result<TR, bool>) -> Result<usize, bool> {
    if tr.is_ok() {
        let t = tr.unwrap();
        return t.magic;
    }
    Err(false)
}

fn false_positive_test<U, T>(x: Result<(), U>) -> Result<(), T>
where
    T: From<U>,
{
    Ok(x?)
}

// not quite needless
fn deref_ref(s: Option<&String>) -> Option<&str> {
    Some(s?)
}

fn main() {}

// #6921 if a macro wraps an expr in Some(  ) and the ? is in the macro use,
// the suggestion fails to apply; do not lint
macro_rules! some_in_macro {
    ($expr:expr) => {
        || -> _ { Some($expr) }()
    };
}

pub fn test1() {
    let x = Some(3);
    let _x = some_in_macro!(x?);
}

// this one is ok because both the ? and the Some are both inside the macro def
macro_rules! some_and_qmark_in_macro {
    ($expr:expr) => {
        || -> Option<_> { Some($expr) }()
    };
}

pub fn test2() {
    let x = Some(3);
    let _x = some_and_qmark_in_macro!(x?);
}

async fn async_option_bad(to: TO) -> Option<usize> {
    let _ = Some(3);
    to.magic
}

async fn async_deref_ref(s: Option<&String>) -> Option<&str> {
    Some(s?)
}

async fn async_result_bad(s: TR) -> Result<usize, bool> {
    s.magic
}