1// run-rustfix
2#![allow(dead_code)]
3#![allow(unused_variables, clippy::unnecessary_wraps)]
4
5fn option_unwrap_or() {
6    // int case
7    Some(1).unwrap_or(42);
8
9    // int case reversed
10    Some(1).unwrap_or(42);
11
12    // richer none expr
13    Some(1).unwrap_or(1 + 42);
14
15    // multiline case
16    #[rustfmt::skip]
17    Some(1).unwrap_or({
18        42 + 42
19            + 42 + 42 + 42
20            + 42 + 42 + 42
21    });
22
23    // string case
24    Some("Bob").unwrap_or("Alice");
25
26    // don't lint
27    match Some(1) {
28        Some(i) => i + 2,
29        None => 42,
30    };
31    match Some(1) {
32        Some(i) => i,
33        None => return,
34    };
35    for j in 0..4 {
36        match Some(j) {
37            Some(i) => i,
38            None => continue,
39        };
40        match Some(j) {
41            Some(i) => i,
42            None => break,
43        };
44    }
45
46    // cases where the none arm isn't a constant expression
47    // are not linted due to potential ownership issues
48
49    // ownership issue example, don't lint
50    struct NonCopyable;
51    let mut option: Option<NonCopyable> = None;
52    match option {
53        Some(x) => x,
54        None => {
55            option = Some(NonCopyable);
56            // some more code ...
57            option.unwrap()
58        },
59    };
60
61    // ownership issue example, don't lint
62    let option: Option<&str> = None;
63    match option {
64        Some(s) => s,
65        None => &format!("{} {}!", "hello", "world"),
66    };
67}
68
69fn result_unwrap_or() {
70    // int case
71    Ok::<i32, &str>(1).unwrap_or(42);
72
73    // int case, scrutinee is a binding
74    let a = Ok::<i32, &str>(1);
75    a.unwrap_or(42);
76
77    // int case, suggestion must surround Result expr with parentheses
78    (Ok(1) as Result<i32, &str>).unwrap_or(42);
79
80    // method call case, suggestion must not surround Result expr `s.method()` with parentheses
81    struct S {}
82    impl S {
83        fn method(self) -> Option<i32> {
84            Some(42)
85        }
86    }
87    let s = S {};
88    s.method().unwrap_or(42);
89
90    // int case reversed
91    Ok::<i32, &str>(1).unwrap_or(42);
92
93    // richer none expr
94    Ok::<i32, &str>(1).unwrap_or(1 + 42);
95
96    // multiline case
97    #[rustfmt::skip]
98    Ok::<i32, &str>(1).unwrap_or({
99        42 + 42
100            + 42 + 42 + 42
101            + 42 + 42 + 42
102    });
103
104    // string case
105    Ok::<&str, &str>("Bob").unwrap_or("Alice");
106
107    // don't lint
108    match Ok::<i32, &str>(1) {
109        Ok(i) => i + 2,
110        Err(_) => 42,
111    };
112    match Ok::<i32, &str>(1) {
113        Ok(i) => i,
114        Err(_) => return,
115    };
116    for j in 0..4 {
117        match Ok::<i32, &str>(j) {
118            Ok(i) => i,
119            Err(_) => continue,
120        };
121        match Ok::<i32, &str>(j) {
122            Ok(i) => i,
123            Err(_) => break,
124        };
125    }
126
127    // don't lint, Err value is used
128    match Ok::<&str, &str>("Alice") {
129        Ok(s) => s,
130        Err(s) => s,
131    };
132    // could lint, but unused_variables takes care of it
133    match Ok::<&str, &str>("Alice") {
134        Ok(s) => s,
135        Err(s) => "Bob",
136    };
137}
138
139// don't lint in const fn
140const fn const_fn_option_unwrap_or() {
141    match Some(1) {
142        Some(s) => s,
143        None => 0,
144    };
145}
146
147const fn const_fn_result_unwrap_or() {
148    match Ok::<&str, &str>("Alice") {
149        Ok(s) => s,
150        Err(_) => "Bob",
151    };
152}
153
154mod issue6965 {
155    macro_rules! some_macro {
156        () => {
157            if 1 > 2 { Some(1) } else { None }
158        };
159    }
160
161    fn test() {
162        let _ = some_macro!().unwrap_or(0);
163    }
164}
165
166use std::rc::Rc;
167fn format_name(name: Option<&Rc<str>>) -> &str {
168    match name {
169        None => "<anon>",
170        Some(name) => name,
171    }
172}
173
174fn implicit_deref_ref() {
175    let _: &str = match Some(&"bye") {
176        None => "hi",
177        Some(s) => s,
178    };
179}
180
181fn main() {}
182