We can't find the internet
Attempting to reconnect
Something went wrong!
Attempting to reconnect
← Modules, Visibility, Testing and Docs step 9 of 22
The five preludes
A new Rust file can use Vec, Option, String and Iterator without any
use line. Those names come from a prelude: a collection of names that
name resolution makes available in every module automatically. A name you
define or import yourself takes priority over a prelude name with the same
spelling.
The Rust Reference lists five preludes. The attribute #![no_implicit_prelude]
(placed at the top of a crate or module) turns most of them off for that module
and the modules inside it.
| prelude | what it provides | removed by #![no_implicit_prelude]? |
|---|---|---|
| standard library | Vec, Option, Iterator, functions such as drop; the contents depend on the edition |
yes |
| extern | the names of crates passed to the compiler, such as std and your dependencies |
yes |
| language | the primitive types bool, char, str, the integer types and f32/f64, plus built-in attributes such as #[inline] |
no |
macro_use |
macros brought in by #[macro_use] extern crate some_crate; (still accepted in edition 2024) |
yes in editions 2018 and later; not in 2015 |
| tool | tool namespaces such as clippy and rustfmt, used in attributes like #[rustfmt::skip] |
yes |
In a module with #![no_implicit_prelude] you can still reach the standard
library through a path that starts with ::, for example
::std::vec::Vec<u8> or ::std::println!. Plain println! is not found
there, and in editions 2018 and later neither is plain std::vec::Vec. With rustc 1.98, some compiler built-in macros
such as concat! and stringify! still resolve in such a module.
Edition differences in the standard-library prelude
An edition (2015, 2018, 2021 or 2024) is a per-crate setting that selects a few language rules. One thing it selects is the version of the standard-library prelude:
- 2015 and 2018 use the same prelude.
- 2021 adds
TryFrom,TryIntoandFromIterator. Older code often starts withuse std::convert::TryInto;. That line still compiles in a 2021 or 2024 crate. With rustc 1.98 it produces no warning by default; the allow-by-default lintredundant_importsreports it if you enable it. - 2024 adds
FutureandIntoFuture.
These additions were tied to editions because a new prelude trait can break
existing code. For example, if your own trait also has a try_into method
for i64, then x.try_into() compiles in edition 2018 but fails in edition
2021 with error E0034 ("multiple applicable items in scope"), because both
traits are now in scope.
Not every addition waits for a new edition. With rustc 1.98, size_of and
the AsyncFn traits are in the prelude of every edition, including 2015.
The task
pub fn needs_import(edition: &str, names: Vec<String>) -> Vec<String>
Return the names from names that are not in scope automatically for the
given edition, which are the ones that would need a use (or a full path).
Keep them in input order. Keep duplicates. An empty names gives an empty
result.
This is a model with a fixed list of names. A name is in scope exactly when it appears in one of these lists:
- Language prelude (every case):
bool,char,str,u8,u16,u32,u64,u128,usize,i8,i16,i32,i64,i128,isize,f32,f64. - Standard prelude for
"2015","2018","2021"and"2024": the 35 names in the starter'sV1constant (AsMut,AsRef,Box,Clone, ...,Unpin,Vec). - Added for
"2021"and"2024":TryFrom,TryInto,FromIterator. - Added for
"2024"only:Future,IntoFuture.
Every other name needs an import, including real prelude items the model
leaves out, such as drop, size_of and AsyncFn. Comparison is exact and
case-sensitive: Vec is in scope, vec and VEC are not.
The edition must match one of the four strings exactly. Any other string,
including "none", "" or "2027", models a module with
#![no_implicit_prelude]: the standard prelude and both edition additions are
absent, but the language prelude remains.
The grader compiles your code with edition 2024, so all five added names are already in scope in your own solution.
Two cases in the tests
Primitive type names never need an import. bool and u32 are in the
language prelude, which #![no_implicit_prelude] does not remove.
Frequently used is not the same as in the prelude. HashMap, Rc and
Ordering are in no edition's prelude. Without an import, edition 2024
reports E0425 ("cannot find type HashMap in this scope"). They need
use std::collections::HashMap;, use std::rc::Rc; and
use std::cmp::Ordering;.
Shadowing a prelude name
Because your own names take priority, a glob import can replace a prelude
name without any warning. If my_prelude exports a type alias named
Result, then after use my_prelude::*; the name Result in that module
refers to the alias, not to std::result::Result.
Your code, saved here
Sign in to access your accepted solutions and saved draft history. You can keep reading the lesson without an account.
Sign in to your accountStuck?
Rust reference solution
Sign in to track your attempts toward unlocking the reference solution.