Repository: rust-analyzer/rust-analyzer
Pull request #9108 (2021-06-02 08:04:08)

Don't show extract into variable assist for unit expressions
**Reproduction:**

```rust
fn main() {
    let mut i = 3;
    $0if i >= 0 {
        i += 1;
    } else {
        i -= 1;
    }$0
}
```

1. Select the snippet of code between the $0's.
2. The extract into variable assist shows up, pushing down the more useful extract into function assist.
3. The resulting output of selecting the extract into variable assist is valid but with the extracted variable having the unit type:
```rust
fn main() {
    let mut i = 3;
    let var_name = if i >= 0 {
        i += 1;
    } else {
        i -= 1;
    };
    var_name
}
```

**Fix:**
- Don't show the extract into variable assist for unit expressions. I could not think of any scenarios where such a variable extraction would be desired.


Patch:
diff --git a/crates/hir_def/src/find_path.rs b/crates/hir_def/src/find_path.rs
index 219ed4c071..ee52794aa8 100644
--- a/crates/hir_def/src/find_path.rs
+++ b/crates/hir_def/src/find_path.rs
@@ -682,11 +682,9 @@ pub struct S;
 //- /main.rs crate:main deps:std
 $0
 //- /std.rs crate:std
-pub mod prelude {
-    pub mod rust_2018 {
-        pub struct S;
-    }
-}
+pub mod prelude { pub struct S; }
+#[prelude_import]
+pub use prelude::*;
         "#,
             "S",
             "S",
@@ -702,11 +700,11 @@ pub mod prelude {
 $0
 //- /std.rs crate:std
 pub mod prelude {
-    pub mod rust_2018 {
-        pub enum Option<T> { Some(T), None }
-        pub use Option::*;
-    }
+    pub enum Option<T> { Some(T), None }
+    pub use Option::*;
 }
+#[prelude_import]
+pub use prelude::*;
         "#;
         check_found_path(code, "None", "None", "None", "None");
         check_found_path(code, "Some", "Some", "Some", "Some");
@@ -1082,11 +1080,11 @@ fn f() {
 }
 //- /std.rs crate:std
 pub mod prelude {
-    pub mod rust_2018 {
-        pub enum Option { None }
-        pub use Option::*;
-    }
+    pub enum Option { None }
+    pub use Option::*;
 }
+#[prelude_import]
+pub use prelude::*;
         "#,
             "None",
             "None",
diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs
index 6b41921ae4..7f9fdb3793 100644
--- a/crates/hir_def/src/nameres/collector.rs
+++ b/crates/hir_def/src/nameres/collector.rs
@@ -5,13 +5,13 @@
 
 use std::iter;
 
-use base_db::{CrateId, Edition, FileId, ProcMacroId};
+use base_db::{CrateId, FileId, ProcMacroId};
 use cfg::{CfgExpr, CfgOptions};
 use hir_expand::{
     ast_id_map::FileAstId,
     builtin_derive::find_builtin_derive,
     builtin_macro::find_builtin_macro,
-    name::{name, AsName, Name},
+    name::{AsName, Name},
     proc_macro::ProcMacroExpander,
     FragmentKind, HirFileId, MacroCallId, MacroCallKind, MacroDefId, MacroDefKind,
 };
@@ -67,6 +67,14 @@ pub(super) fn collect_defs(
             def_map
                 .extern_prelude
                 .insert(dep.as_name(), dep_def_map.module_id(dep_def_map.root).into());
+
+            // look for the prelude
+            // If the dependency defines a prelude, we overwrite an already defined
+            // prelude. This is necessary to import the "std" prelude if a crate
+            // depends on both "core" and "std".
+            if dep_def_map.prelude.is_some() {
+                def_map.prelude = dep_def_map.prelude;
+            }
         }
     }
 
@@ -275,8 +283,6 @@ impl DefCollector<'_> {
 
         let attrs = item_tree.top_level_attrs(self.db, self.def_map.krate);
         if attrs.cfg().map_or(true, |cfg| self.cfg_options.check(&cfg) != Some(false)) {
-            self.inject_prelude(&attrs);
-
             // Process other crate-level attributes.
             for attr in &*attrs {
                 let attr_name = match attr.path.as_ident() {
@@ -454,71 +460,6 @@ impl DefCollector<'_> {
         }
     }
 
-    fn inject_prelude(&mut self, crate_attrs: &Attrs) {
-        // See compiler/rustc_builtin_macros/src/standard_library_imports.rs
-
-        if crate_attrs.by_key("no_core").exists() {
-            // libcore does not get a prelude.
-            return;
-        }
-
-        let krate = if crate_attrs.by_key("no_std").exists() {
-            name![core]
-        } else {
-            let std = name![std];
-            if self.def_map.extern_prelude().any(|(name, _)| *name == std) {
-                std
-            } else {
-                // If `std` does not exist for some reason, fall back to core. This mostly helps
-                // keep r-a's own tests minimal.
-                name![core]
-            }
-        };
-
-        let edition = match self.def_map.edition {
-            Edition::Edition2015 => name![rust_2015],
-            Edition::Edition2018 => name![rust_2018],
-            Edition::Edition2021 => name![rust_2021],
-        };
-
-        let path_kind = if self.def_map.edition == Edition::Edition2015 {
-            PathKind::Plain
-        } else {
-            PathKind::Abs
-        };
-        let path = ModPath::from_segments(
-            path_kind.clone(),
-            [krate.clone(), name![prelude], edition].iter().cloned(),
-        );
-        // Fall back to the older `std::prelude::v1` for compatibility with Rust <1.52.0
-        // FIXME remove this fallback
-        let fallback_path =
-            ModPath::from_segments(path_kind, [krate, name![prelude], name![v1]].iter().cloned());
-
-        for path in &[path, fallback_path] {
-            let (per_ns, _) = self.def_map.resolve_path(
-                self.db,
-                self.def_map.root,
-                &path,
-                BuiltinShadowMode::Other,
-            );
-
-            match &per_ns.types {
-                Some((ModuleDefId::ModuleId(m), _)) => {
-                    self.def_map.prelude = Some(*m);
-                    return;
-                }
-                _ => {
-                    log::debug!(
-                        "could not resolve prelude path `{}` to module (resolved to {:?})",
-                        path,
-                        per_ns.types
-                    );
-                }
-            }
-        }
-    }
-
     /// Adds a definition of procedural macro `name` to the root module.
     ///
     /// # Notes on procedural macro resolution
@@ -777,8 +718,6 @@ impl DefCollector<'_> {
             match def.take_types() {
                 Some(ModuleDefId::ModuleId(m)) => {
                     if import.is_prelude {
-                        // Note: This dodgily overrides the injected prelude. The rustc
-                        // implementation seems to work the same though.
                         cov_mark::hit!(std_prelude);
                         self.def_map.prelude = Some(m);
                     } else if m.krate != self.def_map.krate {
diff --git a/crates/hir_expand/src/name.rs b/crates/hir_expand/src/name.rs
index 00b8adc1eb..b07fbf8b3f 100644
--- a/crates/hir_expand/src/name.rs
+++ b/crates/hir_expand/src/name.rs
@@ -176,11 +176,6 @@ pub mod known {
         result,
         boxed,
         option,
-        prelude,
-        rust_2015,
-        rust_2018,
-        rust_2021,
-        v1,
         // Components of known path (type name)
         Iterator,
         IntoIterator,
diff --git a/crates/ide_assists/src/handlers/extract_variable.rs b/crates/ide_assists/src/handlers/extract_variable.rs
index ae084c86c2..46b54a5f54 100644
--- a/crates/ide_assists/src/handlers/extract_variable.rs
+++ b/crates/ide_assists/src/handlers/extract_variable.rs
@@ -36,6 +36,11 @@ pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext) -> Option
         return None;
     }
     let to_extract = node.ancestors().find_map(valid_target_expr)?;
+    if let Some(ty) = ctx.sema.type_of_expr(&to_extract) {
+        if ty.is_unit() {
+            return None;
+        }
+    }
     let anchor = Anchor::from(&to_extract)?;
     let indent = anchor.syntax().prev_sibling_or_token()?.as_token()?.clone();
     let target = to_extract.syntax().text_range();
@@ -275,15 +280,23 @@ fn foo() {
         check_assist(
             extract_variable,
             r#"
-fn foo() {
+fn foo() -> i32 {
     $0bar(1 + 1)$0
 }
+
+fn bar(i: i32) -> i32 {
+    i
+}
 "#,
             r#"
-fn foo() {
+fn foo() -> i32 {
     let $0bar = bar(1 + 1);
     bar
 }
+
+fn bar(i: i32) -> i32 {
+    i
+}
 "#,
         )
     }
@@ -796,6 +809,22 @@ fn foo() {
         check_assist_not_applicable(extract_variable, "fn main() { loop { $0break$0; }; }");
     }
 
+    #[test]
+    fn test_extract_var_unit_expr_not_applicable() {
+        check_assist_not_applicable(
+            extract_variable,
+            r#"
+fn foo() {
+    let mut i = 3;
+    $0if i >= 0 {
+        i += 1;
+    } else {
+        i -= 1;
+    }$0
+}"#,
+        );
+    }
+
     // FIXME: This is not quite correct, but good enough(tm) for the sorting heuristic
     #[test]
     fn extract_var_target() {
diff --git a/crates/ide_completion/src/completions/unqualified_path.rs b/crates/ide_completion/src/completions/unqualified_path.rs
index bd955aa85c..20188a7ddc 100644
--- a/crates/ide_completion/src/completions/unqualified_path.rs
+++ b/crates/ide_completion/src/completions/unqualified_path.rs
@@ -385,11 +385,10 @@ fn foo() {
 fn foo() { let x: $0 }
 
 //- /std/lib.rs crate:std
-pub mod prelude {
-    pub mod rust_2018 {
-        pub struct Option;
-    }
-}
+#[prelude_import]
+use prelude::*;
+
+mod prelude { struct Option; }
 "#,
             expect![[r#"
                 fn foo()  fn()
@@ -407,10 +406,12 @@ pub mod prelude {
 fn f() {$0}
 
 //- /std/lib.rs crate:std
-pub mod prelude {
-    pub mod rust_2018 {
-        pub use crate::concat;
-    }
+#[prelude_import]
+pub use prelude::*;
+
+#[macro_use]
+mod prelude {
+    pub use crate::concat;
 }
 
 mod macros {
@@ -435,18 +436,16 @@ mod macros {
 fn foo() { let x: $0 }
 
 //- /core/lib.rs crate:core
-pub mod prelude {
-    pub mod rust_2018 {
-        pub struct Option;
-    }
-}
+#[prelude_import]
+use prelude::*;
+
+mod prelude { struct Option; }
 
 //- /std/lib.rs crate:std deps:core
-pub mod prelude {
-    pub mod rust_2018 {
-        pub struct String;
-    }
-}
+#[prelude_import]
+use prelude::*;
+
+mod prelude { struct String; }
 "#,
             expect![[r#"
                 fn foo()  fn()
diff --git a/crates/ide_db/src/helpers/famous_defs_fixture.rs b/crates/ide_db/src/helpers/famous_defs_fixture.rs
index 3128519661..29ae12dcf4 100644
--- a/crates/ide_db/src/helpers/famous_defs_fixture.rs
+++ b/crates/ide_db/src/helpers/famous_defs_fixture.rs
@@ -128,19 +128,17 @@ pub mod option {
 }
 
 pub mod prelude {
-    pub mod rust_2018 {
-        pub use crate::{
-            cmp::Ord,
-            convert::{From, Into},
-            default::Default,
-            iter::{IntoIterator, Iterator},
-            ops::{Fn, FnMut, FnOnce},
-            option::Option::{self, *},
-        };
-    }
+    pub use crate::{
+        cmp::Ord,
+        convert::{From, Into},
+        default::Default,
+        iter::{IntoIterator, Iterator},
+        ops::{Fn, FnMut, FnOnce},
+        option::Option::{self, *},
+    };
 }
 #[prelude_import]
-pub use prelude::rust_2018::*;
+pub use prelude::*;
 //- /libstd.rs crate:std deps:core
 //! Signatures of traits, types and functions from the std lib for use in tests.
 
@@ -150,4 +148,4 @@ mod return_keyword {}
 /// Docs for prim_str
 mod prim_str {}
 
-pub use core::ops;
+pub use core::ops;
\ No newline at end of file


Test patch:
diff --git a/crates/hir_def/src/nameres/tests.rs b/crates/hir_def/src/nameres/tests.rs
index 58c01354a4..9f652731d9 100644
--- a/crates/hir_def/src/nameres/tests.rs
+++ b/crates/hir_def/src/nameres/tests.rs
@@ -246,16 +246,15 @@ fn std_prelude() {
     check(
         r#"
 //- /main.rs crate:main deps:test_crate
-#[prelude_import]
-use ::test_crate::prelude::*;
-
 use Foo::*;
 
 //- /lib.rs crate:test_crate
-pub mod prelude;
+mod prelude;
+#[prelude_import]
+use prelude::*;
 
 //- /prelude.rs
-pub enum Foo { Bar, Baz }
+pub enum Foo { Bar, Baz };
 "#,
         expect![[r#"
             crate
@@ -467,74 +466,6 @@ pub struct Bar;
     );
 }
 
-#[test]
-fn no_std_prelude() {
-    check(
-        r#"
-        //- /main.rs crate:main deps:core,std
-        #![cfg_attr(not(never), no_std)]
-        use Rust;
-
-        //- /core.rs crate:core
-        pub mod prelude {
-            pud mod rust_2018 {
-                pub struct Rust;
-            }
-        }
-        //- /std.rs crate:std deps:core
-        pub mod prelude {
-            pud mod rust_2018 {
-            }
-        }
-    "#,
-        expect![[r#"
-        crate
-        Rust: t v
-    "#]],
-    );
-}
-
-#[test]
-fn edition_specific_preludes() {
-    // We can't test the 2015 prelude here since you can't reexport its contents with 2015's
-    // absolute paths.
-
-    check(
-        r#"
-        //- /main.rs edition:2018 crate:main deps:std
-        use Rust2018;
-
-        //- /std.rs crate:std
-        pub mod prelude {
-            pud mod rust_2018 {
-                pub struct Rust2018;
-            }
-        }
-    "#,
-        expect![[r#"
-        crate
-        Rust2018: t v
-    "#]],
-    );
-    check(
-        r#"
-        //- /main.rs edition:2021 crate:main deps:std
-        use Rust2021;
-
-        //- /std.rs crate:std
-        pub mod prelude {
-            pud mod rust_2021 {
-                pub struct Rust2021;
-            }
-        }
-    "#,
-        expect![[r#"
-        crate
-        Rust2021: t v
-    "#]],
-    );
-}
-
 #[test]
 fn std_prelude_takes_precedence_above_core_prelude() {
     check(
@@ -543,18 +474,18 @@ fn std_prelude_takes_precedence_above_core_prelude() {
 use {Foo, Bar};
 
 //- /std.rs crate:std deps:core
-pub mod prelude {
-    pub mod rust_2018 {
-        pub struct Foo;
-        pub use core::prelude::rust_2018::Bar;
-    }
+#[prelude_import]
+pub use self::prelude::*;
+mod prelude {
+    pub struct Foo;
+    pub use core::prelude::Bar;
 }
 
 //- /core.rs crate:core
-pub mod prelude {
-    pub mod rust_2018 {
-        pub struct Bar;
-    }
+#[prelude_import]
+pub use self::prelude::*;
+mod prelude {
+    pub struct Bar;
 }
 "#,
         expect![[r#"
@@ -573,15 +504,15 @@ fn cfg_not_test() {
 use {Foo, Bar, Baz};
 
 //- /lib.rs crate:std
-pub mod prelude {
-    pub mod rust_2018 {
-        #[cfg(test)]
-        pub struct Foo;
-        #[cfg(not(test))]
-        pub struct Bar;
-        #[cfg(all(not(any()), feature = "foo", feature = "bar", opt = "42"))]
-        pub struct Baz;
-    }
+#[prelude_import]
+pub use self::prelude::*;
+mod prelude {
+    #[cfg(test)]
+    pub struct Foo;
+    #[cfg(not(test))]
+    pub struct Bar;
+    #[cfg(all(not(any()), feature = "foo", feature = "bar", opt = "42"))]
+    pub struct Baz;
 }
 "#,
         expect![[r#"
@@ -601,15 +532,15 @@ fn cfg_test() {
 use {Foo, Bar, Baz};
 
 //- /lib.rs crate:std cfg:test,feature=foo,feature=bar,opt=42
-pub mod prelude {
-    pub mod rust_2018 {
-        #[cfg(test)]
-        pub struct Foo;
-        #[cfg(not(test))]
-        pub struct Bar;
-        #[cfg(all(not(any()), feature = "foo", feature = "bar", opt = "42"))]
-        pub struct Baz;
-    }
+#[prelude_import]
+pub use self::prelude::*;
+mod prelude {
+    #[cfg(test)]
+    pub struct Foo;
+    #[cfg(not(test))]
+    pub struct Bar;
+    #[cfg(all(not(any()), feature = "foo", feature = "bar", opt = "42"))]
+    pub struct Baz;
 }
 "#,
         expect![[r#"
diff --git a/crates/hir_def/src/nameres/tests/macros.rs b/crates/hir_def/src/nameres/tests/macros.rs
index 3716184386..3065efd65e 100644
--- a/crates/hir_def/src/nameres/tests/macros.rs
+++ b/crates/hir_def/src/nameres/tests/macros.rs
@@ -264,7 +264,7 @@ fn prelude_is_macro_use() {
     cov_mark::check!(prelude_is_macro_use);
     check(
         r#"
-//- /main.rs crate:main deps:std
+//- /main.rs crate:main deps:foo
 structs!(Foo);
 structs_priv!(Bar);
 structs_outside!(Out);
@@ -276,20 +276,21 @@ mod bar;
 structs!(Baz);
 crate::structs!(MacroNotResolved3);
 
-//- /lib.rs crate:std
-pub mod prelude {
-    pub mod rust_2018 {
+//- /lib.rs crate:foo
+#[prelude_import]
+use self::prelude::*;
+
+mod prelude {
+    #[macro_export]
+    macro_rules! structs {
+        ($i:ident) => { struct $i; }
+    }
+
+    mod priv_mod {
         #[macro_export]
-        macro_rules! structs {
+        macro_rules! structs_priv {
             ($i:ident) => { struct $i; }
         }
-
-        mod priv_mod {
-            #[macro_export]
-            macro_rules! structs_priv {
-                ($i:ident) => { struct $i; }
-            }
-        }
     }
 }
 
@@ -616,11 +617,12 @@ fn macro_dollar_crate_is_correct_in_indirect_deps() {
 foo!();
 
 //- /std.rs crate:std deps:core
+#[prelude_import]
+use self::prelude::*;
+
 pub use core::foo;
 
-pub mod prelude {
-    pub mod rust_2018 {}
-}
+mod prelude {}
 
 #[macro_use]
 mod std_macros;
diff --git a/crates/hir_ty/src/tests/macros.rs b/crates/hir_ty/src/tests/macros.rs
index d14103aab1..7647bb08b7 100644
--- a/crates/hir_ty/src/tests/macros.rs
+++ b/crates/hir_ty/src/tests/macros.rs
@@ -982,18 +982,14 @@ fn test() {
 }         //^ S
 
 //- /lib.rs crate:core
-pub mod prelude {
-    pub mod rust_2018 {
-        #[rustc_builtin_macro]
-        pub macro Clone {}
-        pub use crate::clone::Clone;
-    }
-}
-
-pub mod clone {
-    pub trait Clone {
+#[prelude_import]
+use clone::*;
+mod clone {
+    trait Clone {
         fn clone(&self) -> Self;
     }
+    #[rustc_builtin_macro]
+    macro Clone {}
 }
 "#,
     );
@@ -1005,22 +1001,14 @@ fn infer_derive_clone_in_core() {
         r#"
 //- /lib.rs crate:core
 #[prelude_import]
-use prelude::rust_2018::*;
-
-pub mod prelude {
-    pub mod rust_2018 {
-        #[rustc_builtin_macro]
-        pub macro Clone {}
-        pub use crate::clone::Clone;
-    }
-}
-
-pub mod clone {
-    pub trait Clone {
+use clone::*;
+mod clone {
+    trait Clone {
         fn clone(&self) -> Self;
     }
+    #[rustc_builtin_macro]
+    macro Clone {}
 }
-
 #[derive(Clone)]
 pub struct S;
 
@@ -1049,18 +1037,14 @@ fn test() {
 }
 
 //- /lib.rs crate:core
-pub mod prelude {
-    pub mod rust_2018 {
-        #[rustc_builtin_macro]
-        pub macro Clone {}
-        pub use crate::clone::Clone;
-    }
-}
-
-pub mod clone {
-    pub trait Clone {
+#[prelude_import]
+use clone::*;
+mod clone {
+    trait Clone {
         fn clone(&self) -> Self;
     }
+    #[rustc_builtin_macro]
+    macro Clone {}
 }
 "#,
     );
diff --git a/crates/hir_ty/src/tests/method_resolution.rs b/crates/hir_ty/src/tests/method_resolution.rs
index 058eb91299..a4c132bc5f 100644
--- a/crates/hir_ty/src/tests/method_resolution.rs
+++ b/crates/hir_ty/src/tests/method_resolution.rs
@@ -796,7 +796,7 @@ fn test() {
 fn method_resolution_trait_from_prelude() {
     check_types(
         r#"
-//- /main.rs crate:main deps:core
+//- /main.rs crate:main deps:other_crate
 struct S;
 impl Clone for S {}
 
@@ -805,12 +805,12 @@ fn test() {
           //^ S
 }
 
-//- /lib.rs crate:core
-pub mod prelude {
-    pub mod rust_2018 {
-        pub trait Clone {
-            fn clone(&self) -> Self;
-        }
+//- /lib.rs crate:other_crate
+#[prelude_import] use foo::*;
+
+mod foo {
+    trait Clone {
+        fn clone(&self) -> Self;
     }
 }
 "#,
diff --git a/crates/hir_ty/src/tests/regression.rs b/crates/hir_ty/src/tests/regression.rs
index 1019e783b5..ad9edf11cd 100644
--- a/crates/hir_ty/src/tests/regression.rs
+++ b/crates/hir_ty/src/tests/regression.rs
@@ -426,12 +426,11 @@ fn test() {
 
 //- /std.rs crate:std
 #[prelude_import]
-use self::prelude::rust_2018::*;
+use prelude::*;
+
 pub mod prelude {
-    pub mod rust_2018 {
-        pub use crate::iter::Iterator;
-        pub use crate::option::Option;
-    }
+    pub use crate::iter::Iterator;
+    pub use crate::option::Option;
 }
 
 pub mod iter {
diff --git a/crates/hir_ty/src/tests/simple.rs b/crates/hir_ty/src/tests/simple.rs
index 3418ed21e7..ac312981df 100644
--- a/crates/hir_ty/src/tests/simple.rs
+++ b/crates/hir_ty/src/tests/simple.rs
@@ -2712,23 +2712,3 @@ fn main() {
         "#]],
     );
 }
-
-#[test]
-fn prelude_2015() {
-    check_types(
-        r#"
-//- /main.rs edition:2015 crate:main deps:core
-fn f() {
-    Rust;
-     //^ Rust
-}
-
-//- /core.rs crate:core
-pub mod prelude {
-    pub mod rust_2015 {
-        pub struct Rust;
-    }
-}
-    "#,
-    );
-}
diff --git a/crates/hir_ty/src/tests/traits.rs b/crates/hir_ty/src/tests/traits.rs
index 588f0d1d41..49add4ab99 100644
--- a/crates/hir_ty/src/tests/traits.rs
+++ b/crates/hir_ty/src/tests/traits.rs
@@ -20,12 +20,11 @@ fn test() {
 } //^ u64
 
 //- /core.rs crate:core
-pub mod prelude {
-    pub mod rust_2018 {
-        #[lang = "future_trait"]
-        pub trait Future {
-            type Output;
-        }
+#[prelude_import] use future::*;
+mod future {
+    #[lang = "future_trait"]
+    trait Future {
+        type Output;
     }
 }
 "#,
@@ -137,15 +136,17 @@ fn test() {
 } //^ i32
 
 //- /core.rs crate:core
-pub mod ops {
-    pub trait Try {
+#[prelude_import] use ops::*;
+mod ops {
+    trait Try {
         type Ok;
         type Error;
     }
 }
 
-pub mod result {
-    pub enum Result<O, E> {
+#[prelude_import] use result::*;
+mod result {
+    enum Result<O, E> {
         Ok(O),
         Err(E)
     }
@@ -155,12 +156,6 @@ pub mod result {
         type Error = E;
     }
 }
-
-pub mod prelude {
-    pub mod rust_2018 {
-        pub use crate::{result::*, ops::*};
-    }
-}
 "#,
     );
 }
@@ -195,7 +190,8 @@ mov convert {
     impl<T> From<T> for T {}
 }
 
-pub mod result {
+#[prelude_import] use result::*;
+mod result {
     use crate::convert::From;
     use crate::ops::{Try, FromResidual};
 
@@ -212,12 +208,6 @@ pub mod result {
 
     impl<T, E, F: From<E>> FromResidual<Result<Infallible, E>> for Result<T, F> {}
 }
-
-pub mod prelude {
-    pub mod rust_2018 {
-        pub use crate::result::*;
-    }
-}
 "#,
     );
 }
@@ -227,7 +217,6 @@ fn infer_for_loop() {
     check_types(
         r#"
 //- /main.rs crate:main deps:core,alloc
-#![no_std]
 use alloc::collections::Vec;
 
 fn test() {
@@ -239,19 +228,14 @@ fn test() {
 }
 
 //- /core.rs crate:core
-pub mod iter {
-    pub trait IntoIterator {
+#[prelude_import] use iter::*;
+mod iter {
+    trait IntoIterator {
         type Item;
     }
 }
-pub mod prelude {
-    pub mod rust_2018 {
-        pub use crate::iter::*;
-    }
-}
 
 //- /alloc.rs crate:alloc deps:core
-#![no_std]
 mod collections {
     struct Vec<T> {}
     impl<T> Vec<T> {