| author | bors <bors@rust-lang.org> 2026-06-30 08:40:27 UTC |
| committer | bors <bors@rust-lang.org> 2026-06-30 08:40:27 UTC |
| log | 51657149e91586571ff1c463bc58239daa1a88d2 |
| tree | 30d0e9a57e5e206ce70bb9e7cb3a52d0695985fb |
| parent | 345632878cffcb4c8e90750e943296b43d16c76e |
| parent | cdfa29797d09d9622fd32cc85c65ea9309ea46df |
Rollup of 7 pull requests
Successful merges:
- rust-lang/rust#158073 (bootstrap: fix panic when repo path contains spaces by switching to CARGO_ENCODED_RUSTFLAGS)
- rust-lang/rust#158256 (Avoid parser panics bubbling out to proc macros)
- rust-lang/rust#158561 (Avoid building rustdoc for tests without doctests)
- rust-lang/rust#158562 (Improve tracing of steps in bootstrap)
- rust-lang/rust#157445 (Allow section override when using patchable-function-entries)
- rust-lang/rust#158327 (Move attribute and keyword docs from `std` to `core`)
- rust-lang/rust#158591 (Fix spacing issue for unused parentheses lint)37 files changed, 3548 insertions(+), 3255 deletions(-)
compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs+37-25| ... | ... | @@ -8,9 +8,9 @@ use rustc_span::edition::Edition::Edition2024; |
| 8 | 8 | use super::prelude::*; |
| 9 | 9 | use crate::attributes::AttributeSafety; |
| 10 | 10 | use crate::session_diagnostics::{ |
| 11 | EmptyExportName, NakedFunctionIncompatibleAttribute, NullOnExport, NullOnObjcClass, | |
| 12 | NullOnObjcSelector, ObjcClassExpectedStringLiteral, ObjcSelectorExpectedStringLiteral, | |
| 13 | SanitizeInvalidStatic, TargetFeatureOnLangItem, | |
| 11 | EmptyExportName, EmptySection, NakedFunctionIncompatibleAttribute, NullOnExport, | |
| 12 | NullOnObjcClass, NullOnObjcSelector, NullOnSection, ObjcClassExpectedStringLiteral, | |
| 13 | ObjcSelectorExpectedStringLiteral, SanitizeInvalidStatic, TargetFeatureOnLangItem, | |
| 14 | 14 | }; |
| 15 | 15 | use crate::target_checking::Policy::AllowSilent; |
| 16 | 16 | |
| ... | ... | @@ -795,7 +795,8 @@ pub(crate) struct PatchableFunctionEntryParser; |
| 795 | 795 | impl SingleAttributeParser for PatchableFunctionEntryParser { |
| 796 | 796 | const PATH: &[Symbol] = &[sym::patchable_function_entry]; |
| 797 | 797 | const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Fn)]); |
| 798 | const TEMPLATE: AttributeTemplate = template!(List: &["prefix_nops = m, entry_nops = n"]); | |
| 798 | const TEMPLATE: AttributeTemplate = | |
| 799 | template!(List: &["prefix_nops = m, entry_nops = n, section = \"section\""]); | |
| 799 | 800 | const STABILITY: AttributeStability = unstable!(patchable_function_entry); |
| 800 | 801 | |
| 801 | 802 | fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> { |
| ... | ... | @@ -803,74 +804,85 @@ impl SingleAttributeParser for PatchableFunctionEntryParser { |
| 803 | 804 | |
| 804 | 805 | let mut prefix = None; |
| 805 | 806 | let mut entry = None; |
| 807 | let mut section = None; | |
| 806 | 808 | |
| 807 | 809 | if meta_item_list.len() == 0 { |
| 808 | 810 | cx.adcx().expected_at_least_one_argument(meta_item_list.span); |
| 809 | 811 | return None; |
| 810 | 812 | } |
| 811 | 813 | |
| 812 | let mut errored = false; | |
| 813 | ||
| 814 | 814 | for item in meta_item_list.mixed() { |
| 815 | 815 | let Some((ident, value)) = cx.expect_name_value(item, item.span(), None) else { |
| 816 | continue; | |
| 816 | return None; | |
| 817 | 817 | }; |
| 818 | 818 | |
| 819 | 819 | let attrib_to_write = match ident.name { |
| 820 | 820 | sym::prefix_nops => { |
| 821 | 821 | // Duplicate prefixes are not allowed |
| 822 | 822 | if prefix.is_some() { |
| 823 | errored = true; | |
| 824 | 823 | cx.adcx().duplicate_key(ident.span, sym::prefix_nops); |
| 825 | continue; | |
| 824 | return None; | |
| 826 | 825 | } |
| 827 | 826 | &mut prefix |
| 828 | 827 | } |
| 829 | 828 | sym::entry_nops => { |
| 830 | 829 | // Duplicate entries are not allowed |
| 831 | 830 | if entry.is_some() { |
| 832 | errored = true; | |
| 833 | 831 | cx.adcx().duplicate_key(ident.span, sym::entry_nops); |
| 834 | continue; | |
| 832 | return None; | |
| 835 | 833 | } |
| 836 | 834 | &mut entry |
| 837 | 835 | } |
| 836 | sym::section => { | |
| 837 | // Duplicate entries are not allowed | |
| 838 | if section.is_some() { | |
| 839 | cx.adcx().duplicate_key(ident.span, sym::section); | |
| 840 | return None; | |
| 841 | } | |
| 842 | // Only a string type value is allowed. | |
| 843 | let Some(value_str) = value.value_as_str() else { | |
| 844 | cx.adcx().expect_string_literal(value); | |
| 845 | return None; | |
| 846 | }; | |
| 847 | // The section name does not allow null characters. | |
| 848 | if value_str.as_str().contains('\0') { | |
| 849 | cx.emit_err(NullOnSection { span: value.value_span }); | |
| 850 | } | |
| 851 | // The section name is not allowed to be empty, LLVM does | |
| 852 | // not allow them. | |
| 853 | if value_str.is_empty() { | |
| 854 | cx.emit_err(EmptySection { span: value.value_span }); | |
| 855 | } | |
| 856 | section = Some(value_str); | |
| 857 | // Integer parsing is not needed, process next item. | |
| 858 | continue; | |
| 859 | } | |
| 838 | 860 | _ => { |
| 839 | errored = true; | |
| 840 | 861 | cx.adcx().expected_specific_argument( |
| 841 | 862 | ident.span, |
| 842 | 863 | &[sym::prefix_nops, sym::entry_nops], |
| 843 | 864 | ); |
| 844 | continue; | |
| 865 | return None; | |
| 845 | 866 | } |
| 846 | 867 | }; |
| 847 | 868 | |
| 848 | 869 | let rustc_ast::LitKind::Int(val, _) = value.value_as_lit().kind else { |
| 849 | errored = true; | |
| 850 | 870 | cx.adcx().expected_integer_literal(value.value_span); |
| 851 | continue; | |
| 871 | return None; | |
| 852 | 872 | }; |
| 853 | 873 | |
| 854 | 874 | let Ok(val) = val.get().try_into() else { |
| 855 | errored = true; | |
| 856 | 875 | cx.adcx().expected_integer_literal_in_range( |
| 857 | 876 | value.value_span, |
| 858 | 877 | u8::MIN as isize, |
| 859 | 878 | u8::MAX as isize, |
| 860 | 879 | ); |
| 861 | continue; | |
| 880 | return None; | |
| 862 | 881 | }; |
| 863 | 882 | |
| 864 | 883 | *attrib_to_write = Some(val); |
| 865 | 884 | } |
| 866 | 885 | |
| 867 | if errored { | |
| 868 | None | |
| 869 | } else { | |
| 870 | Some(AttributeKind::PatchableFunctionEntry { | |
| 871 | prefix: prefix.unwrap_or(0), | |
| 872 | entry: entry.unwrap_or(0), | |
| 873 | }) | |
| 874 | } | |
| 886 | Some(AttributeKind::PatchableFunctionEntry { prefix, entry, section }) | |
| 875 | 887 | } |
| 876 | 888 | } |
compiler/rustc_attr_parsing/src/session_diagnostics.rs+14| ... | ... | @@ -292,6 +292,13 @@ pub(crate) struct EmptyExportName { |
| 292 | 292 | pub span: Span, |
| 293 | 293 | } |
| 294 | 294 | |
| 295 | #[derive(Diagnostic)] | |
| 296 | #[diag("`section` may not be empty")] | |
| 297 | pub(crate) struct EmptySection { | |
| 298 | #[primary_span] | |
| 299 | pub span: Span, | |
| 300 | } | |
| 301 | ||
| 295 | 302 | #[derive(Diagnostic)] |
| 296 | 303 | #[diag("`export_name` may not contain null characters", code = E0648)] |
| 297 | 304 | pub(crate) struct NullOnExport { |
| ... | ... | @@ -327,6 +334,13 @@ pub(crate) struct NullOnObjcSelector { |
| 327 | 334 | pub span: Span, |
| 328 | 335 | } |
| 329 | 336 | |
| 337 | #[derive(Diagnostic)] | |
| 338 | #[diag("`section` may not contain null characters", code = E0648)] | |
| 339 | pub(crate) struct NullOnSection { | |
| 340 | #[primary_span] | |
| 341 | pub span: Span, | |
| 342 | } | |
| 343 | ||
| 330 | 344 | #[derive(Diagnostic)] |
| 331 | 345 | #[diag("`objc::class!` expected a string literal")] |
| 332 | 346 | pub(crate) struct ObjcClassExpectedStringLiteral { |
compiler/rustc_codegen_llvm/src/attributes.rs+27-5| ... | ... | @@ -89,11 +89,26 @@ fn patchable_function_entry_attrs<'ll>( |
| 89 | 89 | attr: Option<PatchableFunctionEntry>, |
| 90 | 90 | ) -> SmallVec<[&'ll Attribute; 2]> { |
| 91 | 91 | let mut attrs = SmallVec::new(); |
| 92 | let patchable_spec = attr.unwrap_or_else(|| { | |
| 93 | PatchableFunctionEntry::from_config(sess.opts.unstable_opts.patchable_function_entry) | |
| 94 | }); | |
| 95 | let entry = patchable_spec.entry(); | |
| 96 | let prefix = patchable_spec.prefix(); | |
| 92 | ||
| 93 | let mut entry = sess.opts.unstable_opts.patchable_function_entry.entry(); | |
| 94 | let mut prefix = sess.opts.unstable_opts.patchable_function_entry.prefix(); | |
| 95 | let mut section = sess.opts.unstable_opts.patchable_function_entry.section(); | |
| 96 | let section_sym; | |
| 97 | ||
| 98 | // Apply attribute specified overrides, if any. | |
| 99 | if let Some(patchable_spec) = attr { | |
| 100 | if let Some(sym) = patchable_spec.section() { | |
| 101 | section_sym = sym; | |
| 102 | section = Some(section_sym.as_str()); | |
| 103 | } | |
| 104 | // Override the nop counts if either is present. If only one is present, the | |
| 105 | // other count is implied to be 0. | |
| 106 | if patchable_spec.entry().is_some() || patchable_spec.prefix().is_some() { | |
| 107 | entry = patchable_spec.entry().unwrap_or(0); | |
| 108 | prefix = patchable_spec.prefix().unwrap_or(0); | |
| 109 | } | |
| 110 | } | |
| 111 | ||
| 97 | 112 | if entry > 0 { |
| 98 | 113 | attrs.push(llvm::CreateAttrStringValue( |
| 99 | 114 | cx.llcx, |
| ... | ... | @@ -108,6 +123,13 @@ fn patchable_function_entry_attrs<'ll>( |
| 108 | 123 | &format!("{}", prefix), |
| 109 | 124 | )); |
| 110 | 125 | } |
| 126 | if let Some(section) = section { | |
| 127 | attrs.push(llvm::CreateAttrStringValue( | |
| 128 | cx.llcx, | |
| 129 | "patchable-function-entry-section", | |
| 130 | section, | |
| 131 | )); | |
| 132 | } | |
| 111 | 133 | attrs |
| 112 | 134 | } |
| 113 | 135 |
compiler/rustc_codegen_llvm/src/context.rs+3-5| ... | ... | @@ -14,7 +14,6 @@ use rustc_data_structures::base_n::{ALPHANUMERIC_ONLY, ToBaseN}; |
| 14 | 14 | use rustc_data_structures::fx::FxHashMap; |
| 15 | 15 | use rustc_data_structures::small_c_str::SmallCStr; |
| 16 | 16 | use rustc_hir::def_id::DefId; |
| 17 | use rustc_middle::middle::codegen_fn_attrs::PatchableFunctionEntry; | |
| 18 | 17 | use rustc_middle::mono::CodegenUnit; |
| 19 | 18 | use rustc_middle::ty::layout::{ |
| 20 | 19 | FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasTypingEnv, LayoutError, LayoutOfHelpers, |
| ... | ... | @@ -343,14 +342,13 @@ pub(crate) unsafe fn create_module<'ll>( |
| 343 | 342 | |
| 344 | 343 | // Add "kcfi-offset" module flag with -Z patchable-function-entry (See |
| 345 | 344 | // https://reviews.llvm.org/D141172). |
| 346 | let pfe = | |
| 347 | PatchableFunctionEntry::from_config(sess.opts.unstable_opts.patchable_function_entry); | |
| 348 | if pfe.prefix() > 0 { | |
| 345 | let patchable_prefix_nops = sess.opts.unstable_opts.patchable_function_entry.prefix(); | |
| 346 | if patchable_prefix_nops > 0 { | |
| 349 | 347 | llvm::add_module_flag_u32( |
| 350 | 348 | llmod, |
| 351 | 349 | llvm::ModuleFlagMergeBehavior::Override, |
| 352 | 350 | "kcfi-offset", |
| 353 | pfe.prefix().into(), | |
| 351 | patchable_prefix_nops.into(), | |
| 354 | 352 | ); |
| 355 | 353 | } |
| 356 | 354 |
compiler/rustc_codegen_ssa/src/codegen_attrs.rs+4-2| ... | ... | @@ -290,9 +290,11 @@ fn process_builtin_attrs( |
| 290 | 290 | AttributeKind::RustcOffloadKernel => { |
| 291 | 291 | codegen_fn_attrs.flags |= CodegenFnAttrFlags::OFFLOAD_KERNEL |
| 292 | 292 | } |
| 293 | AttributeKind::PatchableFunctionEntry { prefix, entry } => { | |
| 293 | AttributeKind::PatchableFunctionEntry { prefix, entry, section } => { | |
| 294 | 294 | codegen_fn_attrs.patchable_function_entry = |
| 295 | Some(PatchableFunctionEntry::from_prefix_and_entry(*prefix, *entry)); | |
| 295 | Some(PatchableFunctionEntry::from_prefix_entry_and_section( | |
| 296 | *prefix, *entry, *section, | |
| 297 | )); | |
| 296 | 298 | } |
| 297 | 299 | AttributeKind::InstrumentFn(instrument_fn) => { |
| 298 | 300 | codegen_fn_attrs.instrument_fn = match instrument_fn { |
compiler/rustc_expand/src/proc_macro_server.rs+13-8| ... | ... | @@ -490,9 +490,11 @@ impl server::Server for Rustc<'_, '_> { |
| 490 | 490 | fn literal_from_str(&mut self, s: &str) -> Result<Literal<Self::Span, Self::Symbol>, String> { |
| 491 | 491 | let name = FileName::proc_macro_source_code(s); |
| 492 | 492 | |
| 493 | let mut parser = | |
| 493 | let mut parser = rustc_errors::catch_fatal_errors(|| { | |
| 494 | 494 | new_parser_from_source_str(self.psess(), name, s.to_owned(), StripTokens::Nothing) |
| 495 | .map_err(cancel_diags_into_string)?; | |
| 495 | }) | |
| 496 | .map_err(|_| String::from("failed to parse to literal"))? | |
| 497 | .map_err(cancel_diags_into_string)?; | |
| 496 | 498 | |
| 497 | 499 | let first_span = parser.token.span.data(); |
| 498 | 500 | let minus_present = parser.eat(exp!(Minus)); |
| ... | ... | @@ -569,12 +571,15 @@ impl server::Server for Rustc<'_, '_> { |
| 569 | 571 | } |
| 570 | 572 | |
| 571 | 573 | fn ts_from_str(&mut self, src: &str) -> Result<Self::TokenStream, String> { |
| 572 | source_str_to_stream( | |
| 573 | self.psess(), | |
| 574 | FileName::proc_macro_source_code(src), | |
| 575 | src.to_string(), | |
| 576 | Some(self.call_site), | |
| 577 | ) | |
| 574 | rustc_errors::catch_fatal_errors(|| { | |
| 575 | source_str_to_stream( | |
| 576 | self.psess(), | |
| 577 | FileName::proc_macro_source_code(src), | |
| 578 | src.to_string(), | |
| 579 | Some(self.call_site), | |
| 580 | ) | |
| 581 | }) | |
| 582 | .map_err(|_| String::from("failed to parse to tokenstream"))? | |
| 578 | 583 | .map_err(cancel_diags_into_string) |
| 579 | 584 | } |
| 580 | 585 |
compiler/rustc_hir/src/attrs/data_structures.rs+3-2| ... | ... | @@ -1271,8 +1271,9 @@ pub enum AttributeKind { |
| 1271 | 1271 | |
| 1272 | 1272 | /// Represents `#[patchable_function_entry]` |
| 1273 | 1273 | PatchableFunctionEntry { |
| 1274 | prefix: u8, | |
| 1275 | entry: u8, | |
| 1274 | prefix: Option<u8>, | |
| 1275 | entry: Option<u8>, | |
| 1276 | section: Option<Symbol>, | |
| 1276 | 1277 | }, |
| 1277 | 1278 | |
| 1278 | 1279 | /// Represents `#[path]` |
compiler/rustc_interface/src/tests.rs+1-1| ... | ... | @@ -866,7 +866,7 @@ fn test_unstable_options_tracking_hash() { |
| 866 | 866 | tracked!(panic_in_drop, PanicStrategy::Abort); |
| 867 | 867 | tracked!( |
| 868 | 868 | patchable_function_entry, |
| 869 | PatchableFunctionEntry::from_total_and_prefix_nops(10, 5) | |
| 869 | PatchableFunctionEntry::from_parts(10, 5, None) | |
| 870 | 870 | .expect("total must be greater than or equal to prefix") |
| 871 | 871 | ); |
| 872 | 872 | tracked!(plt, Some(true)); |
compiler/rustc_lint/src/unused.rs+1-1| ... | ... | @@ -338,7 +338,7 @@ trait UnusedDelimLint { |
| 338 | 338 | && !snip.starts_with(' ') |
| 339 | 339 | { |
| 340 | 340 | " " |
| 341 | } else if let Ok(snip) = sm.span_to_prev_source(value_span) | |
| 341 | } else if let Ok(snip) = sm.span_to_next_source(value_span) | |
| 342 | 342 | && snip.starts_with(|c: char| c.is_alphanumeric()) |
| 343 | 343 | { |
| 344 | 344 | " " |
compiler/rustc_middle/src/middle/codegen_fn_attrs.rs+17-8| ... | ... | @@ -114,7 +114,7 @@ pub struct CodegenFnAttrs { |
| 114 | 114 | // FIXME(#82232, #143834): temporarily renamed to mitigate `#[align]` nameres ambiguity |
| 115 | 115 | pub alignment: Option<Align>, |
| 116 | 116 | /// The `#[patchable_function_entry(...)]` attribute. Indicates how many nops should be around |
| 117 | /// the function entry. | |
| 117 | /// the function entry, or override default section to record entry location. | |
| 118 | 118 | pub patchable_function_entry: Option<PatchableFunctionEntry>, |
| 119 | 119 | /// The `#[rustc_objc_class = "..."]` attribute. |
| 120 | 120 | pub objc_class: Option<Symbol>, |
| ... | ... | @@ -162,24 +162,33 @@ pub struct TargetFeature { |
| 162 | 162 | #[derive(Copy, Clone, Debug, TyEncodable, TyDecodable, StableHash)] |
| 163 | 163 | pub struct PatchableFunctionEntry { |
| 164 | 164 | /// Nops to prepend to the function |
| 165 | prefix: u8, | |
| 165 | prefix: Option<u8>, | |
| 166 | 166 | /// Nops after entry, but before body |
| 167 | entry: u8, | |
| 167 | entry: Option<u8>, | |
| 168 | /// Optional, specific section to record entry location in | |
| 169 | section: Option<Symbol>, | |
| 168 | 170 | } |
| 169 | 171 | |
| 170 | 172 | impl PatchableFunctionEntry { |
| 171 | pub fn from_config(config: rustc_session::config::PatchableFunctionEntry) -> Self { | |
| 172 | Self { prefix: config.prefix(), entry: config.entry() } | |
| 173 | pub fn from_prefix_entry_and_section( | |
| 174 | prefix: Option<u8>, | |
| 175 | entry: Option<u8>, | |
| 176 | section: Option<Symbol>, | |
| 177 | ) -> Self { | |
| 178 | Self { prefix, entry, section } | |
| 173 | 179 | } |
| 174 | 180 | pub fn from_prefix_and_entry(prefix: u8, entry: u8) -> Self { |
| 175 | Self { prefix, entry } | |
| 181 | Self { prefix: Some(prefix), entry: Some(entry), section: None } | |
| 176 | 182 | } |
| 177 | pub fn prefix(&self) -> u8 { | |
| 183 | pub fn prefix(&self) -> Option<u8> { | |
| 178 | 184 | self.prefix |
| 179 | 185 | } |
| 180 | pub fn entry(&self) -> u8 { | |
| 186 | pub fn entry(&self) -> Option<u8> { | |
| 181 | 187 | self.entry |
| 182 | 188 | } |
| 189 | pub fn section(&self) -> Option<Symbol> { | |
| 190 | self.section | |
| 191 | } | |
| 183 | 192 | } |
| 184 | 193 | |
| 185 | 194 | #[derive(Clone, Copy, PartialEq, Eq, TyEncodable, TyDecodable, StableHash)] |
compiler/rustc_session/src/config.rs+12-3| ... | ... | @@ -3342,23 +3342,29 @@ impl DumpMonoStatsFormat { |
| 3342 | 3342 | |
| 3343 | 3343 | /// `-Z patchable-function-entry` representation - how many nops to put before and after function |
| 3344 | 3344 | /// entry. |
| 3345 | #[derive(Clone, Copy, PartialEq, Hash, Debug, Default)] | |
| 3345 | #[derive(Clone, PartialEq, Hash, Debug, Default)] | |
| 3346 | 3346 | pub struct PatchableFunctionEntry { |
| 3347 | 3347 | /// Nops before the entry |
| 3348 | 3348 | prefix: u8, |
| 3349 | 3349 | /// Nops after the entry |
| 3350 | 3350 | entry: u8, |
| 3351 | /// An optional section name to record the entry location | |
| 3352 | section: Option<String>, | |
| 3351 | 3353 | } |
| 3352 | 3354 | |
| 3353 | 3355 | impl PatchableFunctionEntry { |
| 3354 | pub fn from_total_and_prefix_nops( | |
| 3356 | pub fn from_parts( | |
| 3355 | 3357 | total_nops: u8, |
| 3356 | 3358 | prefix_nops: u8, |
| 3359 | section: Option<String>, | |
| 3357 | 3360 | ) -> Option<PatchableFunctionEntry> { |
| 3358 | 3361 | if total_nops < prefix_nops { |
| 3359 | 3362 | None |
| 3363 | // Section name cannot contain null characters. | |
| 3364 | } else if section.as_ref().map(|x| x.contains('\0') || x.is_empty()).unwrap_or(false) { | |
| 3365 | None | |
| 3360 | 3366 | } else { |
| 3361 | Some(Self { prefix: prefix_nops, entry: total_nops - prefix_nops }) | |
| 3367 | Some(Self { prefix: prefix_nops, entry: total_nops - prefix_nops, section }) | |
| 3362 | 3368 | } |
| 3363 | 3369 | } |
| 3364 | 3370 | pub fn prefix(&self) -> u8 { |
| ... | ... | @@ -3367,6 +3373,9 @@ impl PatchableFunctionEntry { |
| 3367 | 3373 | pub fn entry(&self) -> u8 { |
| 3368 | 3374 | self.entry |
| 3369 | 3375 | } |
| 3376 | pub fn section(&self) -> Option<&str> { | |
| 3377 | self.section.as_ref().map(|x| x.as_str()) | |
| 3378 | } | |
| 3370 | 3379 | } |
| 3371 | 3380 | |
| 3372 | 3381 | /// `-Zpolonius` values, enabling the borrow checker polonius analysis, and which version: legacy, |
compiler/rustc_session/src/options.rs+11-7| ... | ... | @@ -784,7 +784,7 @@ mod desc { |
| 784 | 784 | pub(crate) const parse_passes: &str = "a space-separated list of passes, or `all`"; |
| 785 | 785 | pub(crate) const parse_panic_strategy: &str = "either `unwind`, `abort`, or `immediate-abort`"; |
| 786 | 786 | pub(crate) const parse_on_broken_pipe: &str = "either `kill`, `error`, or `inherit`"; |
| 787 | pub(crate) const parse_patchable_function_entry: &str = "either two comma separated integers (total_nops,prefix_nops), with prefix_nops <= total_nops, or one integer (total_nops)"; | |
| 787 | pub(crate) const parse_patchable_function_entry: &str = "a comma separated list of (prefix_nops,total_nops,section_name), (prefix_nops,total_nops), or (total_nops). Where prefix_nops <= total_nops where 0 < total_nops <= 255 and prefix_nops <= total_nops"; | |
| 788 | 788 | pub(crate) const parse_opt_panic_strategy: &str = parse_panic_strategy; |
| 789 | 789 | pub(crate) const parse_relro_level: &str = "one of: `full`, `partial`, or `off`"; |
| 790 | 790 | pub(crate) const parse_sanitizers: &str = "comma separated list of sanitizers: `address`, `cfi`, `dataflow`, `hwaddress`, `kcfi`, `kernel-address`, `kernel-hwaddress`, `leak`, `memory`, `memtag`, `safestack`, `shadow-call-stack`, `thread`, or 'realtime'"; |
| ... | ... | @@ -1206,20 +1206,24 @@ pub mod parse { |
| 1206 | 1206 | ) -> bool { |
| 1207 | 1207 | let mut total_nops = 0; |
| 1208 | 1208 | let mut prefix_nops = 0; |
| 1209 | let mut section = None; | |
| 1209 | 1210 | |
| 1210 | 1211 | if !parse_number(&mut total_nops, v) { |
| 1211 | let parts = v.and_then(|v| v.split_once(',')).unzip(); | |
| 1212 | if !parse_number(&mut total_nops, parts.0) { | |
| 1212 | let parts: Vec<_> = v.unwrap_or("").split(',').collect(); | |
| 1213 | if parts.len() < 2 || parts.len() > 3 { | |
| 1213 | 1214 | return false; |
| 1214 | 1215 | } |
| 1215 | if !parse_number(&mut prefix_nops, parts.1) { | |
| 1216 | ||
| 1217 | if !parse_number(&mut total_nops, Some(parts[0])) { | |
| 1218 | return false; | |
| 1219 | } | |
| 1220 | if !parse_number(&mut prefix_nops, Some(parts[1])) { | |
| 1216 | 1221 | return false; |
| 1217 | 1222 | } |
| 1223 | section = parts.get(2).map(|x| x.to_string()); | |
| 1218 | 1224 | } |
| 1219 | 1225 | |
| 1220 | if let Some(pfe) = | |
| 1221 | PatchableFunctionEntry::from_total_and_prefix_nops(total_nops, prefix_nops) | |
| 1222 | { | |
| 1226 | if let Some(pfe) = PatchableFunctionEntry::from_parts(total_nops, prefix_nops, section) { | |
| 1223 | 1227 | *slot = pfe; |
| 1224 | 1228 | return true; |
| 1225 | 1229 | } |
compiler/rustc_span/src/symbol.rs+1| ... | ... | @@ -1874,6 +1874,7 @@ symbols! { |
| 1874 | 1874 | saturating_sub, |
| 1875 | 1875 | sdylib, |
| 1876 | 1876 | search_unbox, |
| 1877 | section, | |
| 1877 | 1878 | select_unpredictable, |
| 1878 | 1879 | self_in_typedefs, |
| 1879 | 1880 | self_struct_ctor, |
library/core/src/attribute_docs.rs created+337| ... | ... | @@ -0,0 +1,337 @@ |
| 1 | #[doc(attribute = "must_use")] | |
| 2 | // | |
| 3 | /// Warn when a value is ignored. | |
| 4 | /// | |
| 5 | /// The `must_use` attribute applies to values where simply creating or returning them is | |
| 6 | /// often not enough. If a value marked with `#[must_use]` is produced and then ignored, the | |
| 7 | /// compiler warns through the [`unused_must_use`] lint. | |
| 8 | /// | |
| 9 | /// This is most common on types that represent an important state or outcome. For example, | |
| 10 | /// [`Result`] is marked `#[must_use]` because ignoring an error value can hide a failed operation. | |
| 11 | /// In the following example, the returned `Result` is the only sign that writing the message | |
| 12 | /// might have failed: | |
| 13 | /// | |
| 14 | /// ```rust | |
| 15 | /// # #![allow(unused_must_use)] | |
| 16 | /// fn write_message() -> std::io::Result<()> { | |
| 17 | /// // Write the message... | |
| 18 | /// Ok(()) | |
| 19 | /// } | |
| 20 | /// | |
| 21 | /// write_message(); | |
| 22 | /// ``` | |
| 23 | /// | |
| 24 | /// Ignoring that `Result` triggers this warning: | |
| 25 | /// | |
| 26 | /// ```text | |
| 27 | /// warning: unused `Result` that must be used | |
| 28 | /// = note: this `Result` may be an `Err` variant, which should be handled | |
| 29 | /// = note: `#[warn(unused_must_use)]` (part of `#[warn(unused)]`) on by default | |
| 30 | /// help: use `let _ = ...` to ignore the resulting value | |
| 31 | /// ``` | |
| 32 | /// | |
| 33 | /// Future values are also `#[must_use]`: creating a future does not run it, so ignoring one often | |
| 34 | /// means the intended asynchronous work never happens. | |
| 35 | /// | |
| 36 | /// You can also place `#[must_use]` on a function, method, or trait declaration. On a function or | |
| 37 | /// method, the warning is tied to ignoring that call's return value: | |
| 38 | /// | |
| 39 | /// ```rust | |
| 40 | /// # #![allow(unused_must_use)] | |
| 41 | /// #[must_use] | |
| 42 | /// fn make_token() -> String { | |
| 43 | /// String::from("token") | |
| 44 | /// } | |
| 45 | /// | |
| 46 | /// // Ignoring this call's return value triggers `unused_must_use`. | |
| 47 | /// make_token(); | |
| 48 | /// ``` | |
| 49 | /// | |
| 50 | /// On a trait, the warning applies when a function returns an opaque type (`impl Trait`) or trait | |
| 51 | /// object (`dyn Trait`) whose bounds include that trait. This is how futures warn if you create one | |
| 52 | /// but never poll or await it, since an `async fn` returns an opaque type implementing [`Future`]. | |
| 53 | /// | |
| 54 | /// The attribute can include a message explaining what the caller should do with the value: | |
| 55 | /// | |
| 56 | /// ```rust | |
| 57 | /// # #![allow(dead_code)] | |
| 58 | /// #[must_use = "call `.finish()` to complete the operation"] | |
| 59 | /// fn start_operation() -> Operation { | |
| 60 | /// Operation | |
| 61 | /// } | |
| 62 | /// | |
| 63 | /// struct Operation; | |
| 64 | /// ``` | |
| 65 | /// | |
| 66 | /// If intentionally ignoring the value is correct, bind it to `_` or call [`drop`]: | |
| 67 | /// | |
| 68 | /// ```rust | |
| 69 | /// # #[must_use] | |
| 70 | /// # fn make_token() -> String { | |
| 71 | /// # String::from("token") | |
| 72 | /// # } | |
| 73 | /// let _ = make_token(); | |
| 74 | /// drop(make_token()); | |
| 75 | /// ``` | |
| 76 | /// | |
| 77 | /// The attribute is a warning tool, not a type-system rule. Code can still explicitly discard a | |
| 78 | /// `#[must_use]` value, and the compiler does not require callers to inspect or otherwise act on | |
| 79 | /// the value. | |
| 80 | /// | |
| 81 | /// For more information, see the Reference on [the `must_use` attribute]. | |
| 82 | /// | |
| 83 | /// [`Result`]: result::Result | |
| 84 | /// [`Future`]: future::Future | |
| 85 | /// [`unused_must_use`]: ../rustc/lints/listing/warn-by-default.html#unused-must-use | |
| 86 | /// [the `must_use` attribute]: ../reference/attributes/diagnostics.html#the-must_use-attribute | |
| 87 | mod must_use_attribute {} | |
| 88 | ||
| 89 | #[doc(attribute = "allow")] | |
| 90 | // | |
| 91 | /// The `allow` attribute suppresses lint diagnostics that would otherwise produce | |
| 92 | /// warnings or errors. It can be used on any lint or lint group (except those | |
| 93 | /// set to `forbid`). | |
| 94 | /// | |
| 95 | /// ```rust | |
| 96 | /// #[allow(dead_code)] | |
| 97 | /// fn unused_function() { | |
| 98 | /// // ... | |
| 99 | /// } | |
| 100 | /// | |
| 101 | /// fn main() { | |
| 102 | /// // `unused_function` does not generate a compiler warning. | |
| 103 | /// } | |
| 104 | /// ``` | |
| 105 | /// | |
| 106 | /// Without `#[allow(dead_code)]`, the example above would emit: | |
| 107 | /// | |
| 108 | /// ```text | |
| 109 | /// warning: function `unused_function` is never used | |
| 110 | /// --> main.rs:1:4 | |
| 111 | /// | | |
| 112 | /// 1 | fn unused_function() { | |
| 113 | /// | ^^^^^^^^^^^^^^^ | |
| 114 | /// | | |
| 115 | /// = note: `#[warn(dead_code)]` (part of `#[warn(unused)]`) on by default | |
| 116 | /// | |
| 117 | /// warning: 1 warning emitted | |
| 118 | /// ``` | |
| 119 | /// | |
| 120 | /// Multiple lints can be set to `allow` at once with commas: | |
| 121 | /// | |
| 122 | /// ```rust | |
| 123 | /// #[allow(unused_variables, unused_mut)] | |
| 124 | /// fn main() { | |
| 125 | /// let mut x: u32 = 42; | |
| 126 | /// } | |
| 127 | /// ``` | |
| 128 | /// | |
| 129 | /// This is mostly used to prevent lint warnings or errors while still under development. | |
| 130 | /// | |
| 131 | /// It cannot override a lint that has been set to `forbid`. | |
| 132 | /// | |
| 133 | /// It's also important to consider that overusing `allow` could make code harder to maintain | |
| 134 | /// and possibly hide issues. To mitigate this issue, using the `expect` attribute is preferred. | |
| 135 | /// | |
| 136 | /// `allow` can be overridden by `warn`, `deny`, and `forbid`. | |
| 137 | /// | |
| 138 | /// The lint checks supported by rustc can be found via `rustc -W help`, | |
| 139 | /// along with their default settings and are documented in [the `rustc` book]. | |
| 140 | /// | |
| 141 | /// [the `rustc` book]: ../rustc/lints/listing/index.html | |
| 142 | /// | |
| 143 | /// For more information, see the Reference on [the `allow` attribute]. | |
| 144 | /// | |
| 145 | /// [the `allow` attribute]: ../reference/attributes/diagnostics.html#lint-check-attributes | |
| 146 | mod allow_attribute {} | |
| 147 | ||
| 148 | #[doc(attribute = "cfg")] | |
| 149 | // | |
| 150 | /// Used for conditional compilation. | |
| 151 | /// | |
| 152 | /// The `cfg` attribute allows compiling an item under specific conditions, otherwise it | |
| 153 | /// will be ignored. | |
| 154 | /// | |
| 155 | /// ```rust | |
| 156 | /// // Only compiles this function for Linux. | |
| 157 | /// #[cfg(target_os = "linux")] | |
| 158 | /// fn platform_specific() { | |
| 159 | /// println!("Running on Linux"); | |
| 160 | /// } | |
| 161 | /// | |
| 162 | /// // Only compiles this function if not for Linux. | |
| 163 | /// #[cfg(not(target_os = "linux"))] | |
| 164 | /// fn platform_specific() { | |
| 165 | /// println!("Running on something else"); | |
| 166 | /// } | |
| 167 | /// ``` | |
| 168 | /// | |
| 169 | /// Depending on the platform you're targeting, only one of these two functions will be considered | |
| 170 | /// during the compilation. | |
| 171 | /// | |
| 172 | /// Conditions can also be combined with `all(...)`, `any(...)`, and `not(...)`. | |
| 173 | /// | |
| 174 | /// * `all`: True if all given predicates are true. | |
| 175 | /// * `any`: True if at least one of the given predicates is true. | |
| 176 | /// * `not`: True if the predicate is false and false if the predicate is true. | |
| 177 | /// | |
| 178 | /// ```rust | |
| 179 | /// #[cfg(all(unix, target_pointer_width = "64"))] | |
| 180 | /// fn unix_64bit() { | |
| 181 | /// } | |
| 182 | /// ``` | |
| 183 | /// | |
| 184 | /// If you want to use this mechanism in an `if` condition in your code, you | |
| 185 | /// can use the [`cfg!`] macro. To conditionally apply an attribute, | |
| 186 | /// see [`cfg_attr`]. | |
| 187 | /// | |
| 188 | /// For more information, see the Reference on [the `cfg` attribute]. | |
| 189 | /// | |
| 190 | /// [`cfg_attr`]: ../reference/conditional-compilation.html#the-cfg_attr-attribute | |
| 191 | /// [the `cfg` attribute]: ../reference/conditional-compilation.html#the-cfg-attribute | |
| 192 | mod cfg_attribute {} | |
| 193 | ||
| 194 | #[doc(attribute = "deny")] | |
| 195 | // | |
| 196 | /// Emits an error, preventing the compilation from finishing, when a lint check has failed. | |
| 197 | /// This is useful for enforcing rules or preventing certain patterns: | |
| 198 | /// | |
| 199 | /// ```rust,compile_fail | |
| 200 | /// #[deny(unused)] | |
| 201 | /// fn foo() { | |
| 202 | /// let x = 42; // Emits an error because x is unused. | |
| 203 | /// } | |
| 204 | /// ``` | |
| 205 | /// | |
| 206 | /// `deny` can be overridden by `allow`, `warn`, and `forbid`: | |
| 207 | /// | |
| 208 | /// ```rust | |
| 209 | /// #![deny(unused)] | |
| 210 | /// | |
| 211 | /// #[allow(unused)] // We override the `deny` for this function. | |
| 212 | /// fn foo() { | |
| 213 | /// let x = 42; // No lint emitted even though `x` is unused. | |
| 214 | /// } | |
| 215 | /// ``` | |
| 216 | /// | |
| 217 | /// Multiple lints can also be set to `deny` at once: | |
| 218 | /// | |
| 219 | /// ```rust,compile_fail | |
| 220 | /// #![deny(unused_imports, unused_variables)] | |
| 221 | /// use std::collections::*; | |
| 222 | /// | |
| 223 | /// fn main() { | |
| 224 | /// let mut x = 10; | |
| 225 | /// } | |
| 226 | /// ``` | |
| 227 | /// | |
| 228 | /// The lint checks supported by rustc can be found via `rustc -W help`, | |
| 229 | /// along with their default settings and are documented in [the `rustc` book]. | |
| 230 | /// | |
| 231 | /// [the `rustc` book]: ../rustc/lints/listing/index.html | |
| 232 | /// | |
| 233 | /// For more information, see the Reference on [the `deny` attribute]. | |
| 234 | /// | |
| 235 | /// [the `deny` attribute]: ../reference/attributes/diagnostics.html#lint-check-attributes | |
| 236 | mod deny_attribute {} | |
| 237 | ||
| 238 | #[doc(attribute = "forbid")] | |
| 239 | // | |
| 240 | /// Emits an error, preventing the compilation from finishing, when a lint check has failed. | |
| 241 | /// | |
| 242 | /// A lint set to `forbid` cannot be overridden by `allow` or `warn`. | |
| 243 | /// Attempting either will result in a compilation error. Writing `#[deny(...)]` on the same lint inside a | |
| 244 | /// `forbid` scope is permitted, but has no effect; the lint remains at the `forbid` level. | |
| 245 | /// | |
| 246 | /// This is useful for enforcing strict policies that should not be relaxed | |
| 247 | /// anywhere in the codebase. Example: | |
| 248 | /// | |
| 249 | /// ```rust | |
| 250 | /// #![forbid(unsafe_code)] | |
| 251 | /// | |
| 252 | /// // This would cause a compilation error if uncommented: | |
| 253 | /// // #[allow(unsafe_code)] // error: cannot override `forbid` | |
| 254 | /// ``` | |
| 255 | /// | |
| 256 | /// Multiple lints can be set to `forbid` at once: | |
| 257 | /// | |
| 258 | /// ```rust | |
| 259 | /// #![forbid(unsafe_code, unused)] | |
| 260 | /// ``` | |
| 261 | /// | |
| 262 | /// The lint checks supported by rustc can be found via `rustc -W help`, | |
| 263 | /// along with their default settings and are documented in [the `rustc` book]. | |
| 264 | /// | |
| 265 | /// [the `rustc` book]: ../rustc/lints/listing/index.html | |
| 266 | /// | |
| 267 | /// For more information, see the Reference on [the `forbid` attribute]. | |
| 268 | /// | |
| 269 | /// [the `forbid` attribute]: ../reference/attributes/diagnostics.html#lint-check-attributes | |
| 270 | mod forbid_attribute {} | |
| 271 | ||
| 272 | #[doc(attribute = "deprecated")] | |
| 273 | // | |
| 274 | /// Emits a warning during compilation when an item with this attribute is used. | |
| 275 | /// `since` and `note` are optional fields giving more detail about why the item is deprecated. | |
| 276 | /// | |
| 277 | /// * `since`: the version since when the item is deprecated. | |
| 278 | /// * `note`: the reason why an item is deprecated. | |
| 279 | /// | |
| 280 | /// Example: | |
| 281 | /// | |
| 282 | /// ```rust | |
| 283 | /// #[deprecated(since = "1.0.0", note = "Use bar instead")] | |
| 284 | /// struct Foo; | |
| 285 | /// struct Bar; | |
| 286 | /// ``` | |
| 287 | /// | |
| 288 | /// `deprecated` attribute helps developers transition away from old code by providing warnings when | |
| 289 | /// deprecated items are used. Note that during `Cargo` builds, warnings on dependencies get silenced | |
| 290 | /// by default, so you may not see a deprecation warning unless you build that dependency directly. | |
| 291 | /// | |
| 292 | /// For more information, see the Reference on [the `deprecated` attribute]. | |
| 293 | /// | |
| 294 | /// [the `deprecated` attribute]: ../reference/attributes/diagnostics.html#the-deprecated-attribute | |
| 295 | mod deprecated_attribute {} | |
| 296 | ||
| 297 | #[doc(attribute = "warn")] | |
| 298 | // | |
| 299 | /// Emits a warning during compilation when a lint check failed. | |
| 300 | /// | |
| 301 | /// Unlike `deny` or `forbid`, `warn` does not produce a hard error: the compilation continues, but | |
| 302 | /// the compiler emits a warning message. `warn` can be overridden by `allow`, `deny`, and `forbid`. | |
| 303 | /// | |
| 304 | /// Example: | |
| 305 | /// | |
| 306 | /// ```rust,compile_fail | |
| 307 | /// #![allow(unused)] | |
| 308 | /// | |
| 309 | /// #[warn(unused)] // We override the allowed `unused` lint. | |
| 310 | /// fn foo() { | |
| 311 | /// // This lint warns by default even without #[warn(unused)] being explicitly set | |
| 312 | /// let x = 42; // warning: unused variable `x` | |
| 313 | /// } | |
| 314 | /// ``` | |
| 315 | /// | |
| 316 | /// | |
| 317 | /// Many lints, including `unused`, are already set to `warn` by default so this attribute is | |
| 318 | /// mainly useful for lints that are normally `allow` by default. | |
| 319 | /// | |
| 320 | /// Multiple lints can be set to `warn` at once: | |
| 321 | /// | |
| 322 | /// ```rust,compile_fail | |
| 323 | /// #[warn(unused_mut, unused_variables)] | |
| 324 | /// fn main() { | |
| 325 | /// let mut x = 42; | |
| 326 | /// } | |
| 327 | /// ``` | |
| 328 | /// | |
| 329 | /// The lint checks supported by rustc can be found via `rustc -W help`, | |
| 330 | /// along with their default settings and are documented in [the `rustc` book]. | |
| 331 | /// | |
| 332 | /// [the `rustc` book]: ../rustc/lints/listing/index.html | |
| 333 | /// | |
| 334 | /// For more information, see the Reference on [the `warn` attribute]. | |
| 335 | /// | |
| 336 | /// [the `warn` attribute]: ../reference/attributes/diagnostics.html#lint-check-attributes | |
| 337 | mod warn_attribute {} |
library/core/src/keyword_docs.rs created+2761| ... | ... | @@ -0,0 +1,2761 @@ |
| 1 | #[doc(keyword = "as")] | |
| 2 | // | |
| 3 | /// Cast between types, rename an import, or qualify paths to associated items. | |
| 4 | /// | |
| 5 | /// # Type casting | |
| 6 | /// | |
| 7 | /// `as` is most commonly used to turn primitive types into other primitive types, but it has other | |
| 8 | /// uses that include turning pointers into addresses, addresses into pointers, and pointers into | |
| 9 | /// other pointers. | |
| 10 | /// | |
| 11 | /// ```rust | |
| 12 | /// let thing1: u8 = 89.0 as u8; | |
| 13 | /// assert_eq!('B' as u32, 66); | |
| 14 | /// assert_eq!(thing1 as char, 'Y'); | |
| 15 | /// let thing2: f32 = thing1 as f32 + 10.5; | |
| 16 | /// assert_eq!(true as u8 + thing2 as u8, 100); | |
| 17 | /// ``` | |
| 18 | /// | |
| 19 | /// In general, any cast that can be performed via ascribing the type can also be done using `as`, | |
| 20 | /// so instead of writing `let x: u32 = 123`, you can write `let x = 123 as u32` (note: `let x: u32 | |
| 21 | /// = 123` would be best in that situation). The same is not true in the other direction, however; | |
| 22 | /// explicitly using `as` allows a few more coercions that aren't allowed implicitly, such as | |
| 23 | /// changing the type of a raw pointer or turning closures into raw pointers. | |
| 24 | /// | |
| 25 | /// `as` can be seen as the primitive for `From` and `Into`: `as` only works with primitives | |
| 26 | /// (`u8`, `bool`, `str`, pointers, ...) whereas `From` and `Into` also works with types like | |
| 27 | /// `String` or `Vec`. | |
| 28 | /// | |
| 29 | /// `as` can also be used with the `_` placeholder when the destination type can be inferred. Note | |
| 30 | /// that this can cause inference breakage and usually such code should use an explicit type for | |
| 31 | /// both clarity and stability. This is most useful when converting pointers using `as *const _` or | |
| 32 | /// `as *mut _` though the [`cast`][const-cast] method is recommended over `as *const _` and it is | |
| 33 | /// [the same][mut-cast] for `as *mut _`: those methods make the intent clearer. | |
| 34 | /// | |
| 35 | /// # Renaming imports | |
| 36 | /// | |
| 37 | /// `as` is also used to rename imports in [`use`] and [`extern crate`][`crate`] statements: | |
| 38 | /// | |
| 39 | /// ``` | |
| 40 | /// # #[allow(unused_imports)] | |
| 41 | /// use std::{mem as memory, net as network}; | |
| 42 | /// // Now you can use the names `memory` and `network` to refer to `std::mem` and `std::net`. | |
| 43 | /// ``` | |
| 44 | /// | |
| 45 | /// # Qualifying paths | |
| 46 | /// | |
| 47 | /// You'll also find with `From` and `Into`, and indeed all traits, that `as` is used for the | |
| 48 | /// _fully qualified path_, a means of disambiguating associated items, i.e. functions, | |
| 49 | /// constants, and types. For example, if you have a type which implements two traits with identical | |
| 50 | /// method names (e.g. `Into::<u32>::into` and `Into::<u64>::into`), you can clarify which method | |
| 51 | /// you'll use with `<MyThing as Into<u32>>::into(my_thing)`[^as-use-from]. This is quite verbose, | |
| 52 | /// but fortunately, Rust's type inference usually saves you from needing this, although it is | |
| 53 | /// occasionally necessary, especially with methods that return a generic type like `Into::into` or | |
| 54 | /// methods that don't take `self`. It's more common to use in macros where it can provide necessary | |
| 55 | /// hygiene. | |
| 56 | /// | |
| 57 | /// [^as-use-from]: You should probably never use this syntax with `Into` and instead write | |
| 58 | /// `T::from(my_thing)`. It just happens that there aren't any great examples for this syntax in | |
| 59 | /// the standard library. Also, at time of writing, the compiler tends to suggest fully-qualified | |
| 60 | /// paths to fix ambiguous `Into::into` calls, so the example should hopefully be familiar. | |
| 61 | /// | |
| 62 | /// # Further reading | |
| 63 | /// | |
| 64 | /// For more information on what `as` is capable of, see the Reference on [type cast expressions], | |
| 65 | /// [renaming imported entities], [renaming `extern` crates] | |
| 66 | /// and [qualified paths]. | |
| 67 | /// | |
| 68 | /// [type cast expressions]: ../reference/expressions/operator-expr.html#type-cast-expressions | |
| 69 | /// [renaming imported entities]: https://doc.rust-lang.org/reference/items/use-declarations.html#as-renames | |
| 70 | /// [renaming `extern` crates]: https://doc.rust-lang.org/reference/items/extern-crates.html#r-items.extern-crate.as | |
| 71 | /// [qualified paths]: ../reference/paths.html#qualified-paths | |
| 72 | /// [`crate`]: keyword.crate.html | |
| 73 | /// [`use`]: keyword.use.html | |
| 74 | /// [const-cast]: pointer::cast | |
| 75 | /// [mut-cast]: primitive.pointer.html#method.cast-1 | |
| 76 | mod as_keyword {} | |
| 77 | ||
| 78 | #[doc(keyword = "break")] | |
| 79 | // | |
| 80 | /// Exit early from a loop or labelled block. | |
| 81 | /// | |
| 82 | /// When `break` is encountered, execution of the associated loop body is | |
| 83 | /// immediately terminated. | |
| 84 | /// | |
| 85 | /// ```rust | |
| 86 | /// let mut last = 0; | |
| 87 | /// | |
| 88 | /// for x in 1..100 { | |
| 89 | /// if x > 12 { | |
| 90 | /// break; | |
| 91 | /// } | |
| 92 | /// last = x; | |
| 93 | /// } | |
| 94 | /// | |
| 95 | /// assert_eq!(last, 12); | |
| 96 | /// println!("{last}"); | |
| 97 | /// ``` | |
| 98 | /// | |
| 99 | /// A break expression is normally associated with the innermost loop enclosing the | |
| 100 | /// `break` but a label can be used to specify which enclosing loop is affected. | |
| 101 | /// | |
| 102 | /// ```rust | |
| 103 | /// 'outer: for i in 1..=5 { | |
| 104 | /// println!("outer iteration (i): {i}"); | |
| 105 | /// | |
| 106 | /// '_inner: for j in 1..=200 { | |
| 107 | /// println!(" inner iteration (j): {j}"); | |
| 108 | /// if j >= 3 { | |
| 109 | /// // breaks from inner loop, lets outer loop continue. | |
| 110 | /// break; | |
| 111 | /// } | |
| 112 | /// if i >= 2 { | |
| 113 | /// // breaks from outer loop, and directly to "Bye". | |
| 114 | /// break 'outer; | |
| 115 | /// } | |
| 116 | /// } | |
| 117 | /// } | |
| 118 | /// println!("Bye."); | |
| 119 | /// ``` | |
| 120 | /// | |
| 121 | /// When associated with `loop`, a break expression may be used to return a value from that loop. | |
| 122 | /// This is only valid with `loop` and not with any other type of loop. | |
| 123 | /// If no value is specified for `break;` it returns `()`. | |
| 124 | /// Every `break` within a loop must return the same type. | |
| 125 | /// | |
| 126 | /// ```rust | |
| 127 | /// let (mut a, mut b) = (1, 1); | |
| 128 | /// let result = loop { | |
| 129 | /// if b > 10 { | |
| 130 | /// break b; | |
| 131 | /// } | |
| 132 | /// let c = a + b; | |
| 133 | /// a = b; | |
| 134 | /// b = c; | |
| 135 | /// }; | |
| 136 | /// // first number in Fibonacci sequence over 10: | |
| 137 | /// assert_eq!(result, 13); | |
| 138 | /// println!("{result}"); | |
| 139 | /// ``` | |
| 140 | /// | |
| 141 | /// It is also possible to exit from any *labelled* block returning the value early. | |
| 142 | /// If no value is specified for `break;` it returns `()`. | |
| 143 | /// | |
| 144 | /// ```rust | |
| 145 | /// let inputs = vec!["Cow", "Cat", "Dog", "Snake", "Cod"]; | |
| 146 | /// | |
| 147 | /// let mut results = vec![]; | |
| 148 | /// for input in inputs { | |
| 149 | /// let result = 'filter: { | |
| 150 | /// if input.len() > 3 { | |
| 151 | /// break 'filter Err("Too long"); | |
| 152 | /// }; | |
| 153 | /// | |
| 154 | /// if !input.contains("C") { | |
| 155 | /// break 'filter Err("No Cs"); | |
| 156 | /// }; | |
| 157 | /// | |
| 158 | /// Ok(input.to_uppercase()) | |
| 159 | /// }; | |
| 160 | /// | |
| 161 | /// results.push(result); | |
| 162 | /// } | |
| 163 | /// | |
| 164 | /// // [Ok("COW"), Ok("CAT"), Err("No Cs"), Err("Too long"), Ok("COD")] | |
| 165 | /// println!("{:?}", results) | |
| 166 | /// ``` | |
| 167 | /// | |
| 168 | /// For more details consult the [Reference on "break expression"] and the [Reference on "break and | |
| 169 | /// loop values"]. | |
| 170 | /// | |
| 171 | /// [Reference on "break expression"]: ../reference/expressions/loop-expr.html#break-expressions | |
| 172 | /// [Reference on "break and loop values"]: | |
| 173 | /// ../reference/expressions/loop-expr.html#break-and-loop-values | |
| 174 | mod break_keyword {} | |
| 175 | ||
| 176 | #[doc(keyword = "const")] | |
| 177 | // | |
| 178 | /// Compile-time constants, compile-time blocks, compile-time evaluable functions, and raw pointers. | |
| 179 | /// | |
| 180 | /// ## Compile-time constants | |
| 181 | /// | |
| 182 | /// Sometimes a certain value is used many times throughout a program, and it can become | |
| 183 | /// inconvenient to copy it over and over. What's more, it's not always possible or desirable to | |
| 184 | /// make it a variable that gets carried around to each function that needs it. In these cases, the | |
| 185 | /// `const` keyword provides a convenient alternative to code duplication: | |
| 186 | /// | |
| 187 | /// ```rust | |
| 188 | /// const THING: u32 = 0xABAD1DEA; | |
| 189 | /// | |
| 190 | /// let foo = 123 + THING; | |
| 191 | /// ``` | |
| 192 | /// | |
| 193 | /// Constants must be explicitly typed; unlike with `let`, you can't ignore their type and let the | |
| 194 | /// compiler figure it out. Any constant value can be defined in a `const`, which in practice happens | |
| 195 | /// to be most things that would be reasonable to have in a constant (barring `const fn`s). For | |
| 196 | /// example, you can't have a [`File`] as a `const`. | |
| 197 | /// | |
| 198 | /// [`File`]: ../std/fs/struct.File.html | |
| 199 | /// | |
| 200 | /// The only lifetime allowed in a constant is `'static`, which is the lifetime that encompasses | |
| 201 | /// all others in a Rust program. For example, if you wanted to define a constant string, it would | |
| 202 | /// look like this: | |
| 203 | /// | |
| 204 | /// ```rust | |
| 205 | /// const WORDS: &'static str = "hello rust!"; | |
| 206 | /// ``` | |
| 207 | /// | |
| 208 | /// Thanks to static lifetime elision, you usually don't have to explicitly use `'static`: | |
| 209 | /// | |
| 210 | /// ```rust | |
| 211 | /// const WORDS: &str = "hello convenience!"; | |
| 212 | /// ``` | |
| 213 | /// | |
| 214 | /// `const` items look remarkably similar to `static` items, which introduces some confusion as | |
| 215 | /// to which one should be used at which times. To put it simply, constants are inlined wherever | |
| 216 | /// they're used, making using them identical to simply replacing the name of the `const` with its | |
| 217 | /// value. Static variables, on the other hand, point to a single location in memory, which all | |
| 218 | /// accesses share. This means that, unlike with constants, they can't have destructors, and act as | |
| 219 | /// a single value across the entire codebase. | |
| 220 | /// | |
| 221 | /// Constants, like statics, should always be in `SCREAMING_SNAKE_CASE`. | |
| 222 | /// | |
| 223 | /// For more detail on `const`, see the [Rust Book] or the [Reference]. | |
| 224 | /// | |
| 225 | /// ## Compile-time blocks | |
| 226 | /// | |
| 227 | /// The `const` keyword can also be used to define a block of code that is evaluated at compile time. | |
| 228 | /// This is useful for ensuring certain computations are completed before optimizations happen, as well as | |
| 229 | /// before runtime. For more details, see the [Reference][const-blocks]. | |
| 230 | /// | |
| 231 | /// ## Compile-time evaluable functions | |
| 232 | /// | |
| 233 | /// The other main use of the `const` keyword is in `const fn`. This marks a function as being | |
| 234 | /// callable in the body of a `const` or `static` item and in array initializers (commonly called | |
| 235 | /// "const contexts"). `const fn` are restricted in the set of operations they can perform, to | |
| 236 | /// ensure that they can be evaluated at compile-time. See the [Reference][const-eval] for more | |
| 237 | /// detail. | |
| 238 | /// | |
| 239 | /// Turning a `fn` into a `const fn` has no effect on run-time uses of that function. | |
| 240 | /// | |
| 241 | /// ## raw pointers | |
| 242 | /// | |
| 243 | /// The `const` keyword is also used in raw pointers in combination with `mut`, as seen in `*const | |
| 244 | /// T` and `*mut T`. More about `const` as used in raw pointers can be read at the Rust docs for the [pointer primitive]. | |
| 245 | /// | |
| 246 | /// [pointer primitive]: pointer | |
| 247 | /// [Rust Book]: ../book/ch03-01-variables-and-mutability.html#constants | |
| 248 | /// [Reference]: ../reference/items/constant-items.html | |
| 249 | /// [const-blocks]: ../reference/expressions/block-expr.html#const-blocks | |
| 250 | /// [const-eval]: ../reference/const_eval.html | |
| 251 | mod const_keyword {} | |
| 252 | ||
| 253 | #[doc(keyword = "continue")] | |
| 254 | // | |
| 255 | /// Skip to the next iteration of a loop. | |
| 256 | /// | |
| 257 | /// When `continue` is encountered, the current iteration is terminated, returning control to the | |
| 258 | /// loop head, typically continuing with the next iteration. | |
| 259 | /// | |
| 260 | /// ```rust | |
| 261 | /// // Printing odd numbers by skipping even ones | |
| 262 | /// for number in 1..=10 { | |
| 263 | /// if number % 2 == 0 { | |
| 264 | /// continue; | |
| 265 | /// } | |
| 266 | /// println!("{number}"); | |
| 267 | /// } | |
| 268 | /// ``` | |
| 269 | /// | |
| 270 | /// Like `break`, `continue` is normally associated with the innermost enclosing loop, but labels | |
| 271 | /// may be used to specify the affected loop. | |
| 272 | /// | |
| 273 | /// ```rust | |
| 274 | /// // Print Odd numbers under 30 with unit <= 5 | |
| 275 | /// 'tens: for ten in 0..3 { | |
| 276 | /// '_units: for unit in 0..=9 { | |
| 277 | /// if unit % 2 == 0 { | |
| 278 | /// continue; | |
| 279 | /// } | |
| 280 | /// if unit > 5 { | |
| 281 | /// continue 'tens; | |
| 282 | /// } | |
| 283 | /// println!("{}", ten * 10 + unit); | |
| 284 | /// } | |
| 285 | /// } | |
| 286 | /// ``` | |
| 287 | /// | |
| 288 | /// See [continue expressions] from the reference for more details. | |
| 289 | /// | |
| 290 | /// [continue expressions]: ../reference/expressions/loop-expr.html#continue-expressions | |
| 291 | mod continue_keyword {} | |
| 292 | ||
| 293 | #[doc(keyword = "crate")] | |
| 294 | // | |
| 295 | /// A Rust binary or library. | |
| 296 | /// | |
| 297 | /// The primary use of the `crate` keyword is as a part of `extern crate` declarations, which are | |
| 298 | /// used to specify a dependency on a crate external to the one it's declared in. Crates are the | |
| 299 | /// fundamental compilation unit of Rust code, and can be seen as libraries or projects. More can | |
| 300 | /// be read about crates in the [Reference]. | |
| 301 | /// | |
| 302 | /// ```rust ignore | |
| 303 | /// extern crate rand; | |
| 304 | /// extern crate my_crate as thing; | |
| 305 | /// extern crate std; // implicitly added to the root of every Rust project | |
| 306 | /// ``` | |
| 307 | /// | |
| 308 | /// The `as` keyword can be used to change what the crate is referred to as in your project. If a | |
| 309 | /// crate name includes a dash, it is implicitly imported with the dashes replaced by underscores. | |
| 310 | /// | |
| 311 | /// `crate` can also be used as in conjunction with `pub` to signify that the item it's attached to | |
| 312 | /// is public only to other members of the same crate it's in. | |
| 313 | /// | |
| 314 | /// ```rust | |
| 315 | /// # #[allow(unused_imports)] | |
| 316 | /// pub(crate) use std::io::Error as IoError; | |
| 317 | /// pub(crate) enum CoolMarkerType { } | |
| 318 | /// pub struct PublicThing { | |
| 319 | /// pub(crate) semi_secret_thing: bool, | |
| 320 | /// } | |
| 321 | /// ``` | |
| 322 | /// | |
| 323 | /// `crate` is also used to represent the absolute path of a module, where `crate` refers to the | |
| 324 | /// root of the current crate. For instance, `crate::foo::bar` refers to the name `bar` inside the | |
| 325 | /// module `foo`, from anywhere else in the same crate. | |
| 326 | /// | |
| 327 | /// [Reference]: ../reference/items/extern-crates.html | |
| 328 | mod crate_keyword {} | |
| 329 | ||
| 330 | #[doc(keyword = "else")] | |
| 331 | // | |
| 332 | /// What expression to evaluate when an [`if`] condition evaluates to [`false`]. | |
| 333 | /// | |
| 334 | /// `else` expressions are optional. When no else expressions are supplied it is assumed to evaluate | |
| 335 | /// to the unit type `()`. | |
| 336 | /// | |
| 337 | /// The type that the `else` blocks evaluate to must be compatible with the type that the `if` block | |
| 338 | /// evaluates to. | |
| 339 | /// | |
| 340 | /// As can be seen below, `else` must be followed by either: `if`, `if let`, or a block `{}` and it | |
| 341 | /// will return the value of that expression. | |
| 342 | /// | |
| 343 | /// ```rust | |
| 344 | /// let result = if true == false { | |
| 345 | /// "oh no" | |
| 346 | /// } else if "something" == "other thing" { | |
| 347 | /// "oh dear" | |
| 348 | /// } else if let Some(200) = "blarg".parse::<i32>().ok() { | |
| 349 | /// "uh oh" | |
| 350 | /// } else { | |
| 351 | /// println!("Sneaky side effect."); | |
| 352 | /// "phew, nothing's broken" | |
| 353 | /// }; | |
| 354 | /// ``` | |
| 355 | /// | |
| 356 | /// Here's another example but here we do not try and return an expression: | |
| 357 | /// | |
| 358 | /// ```rust | |
| 359 | /// if true == false { | |
| 360 | /// println!("oh no"); | |
| 361 | /// } else if "something" == "other thing" { | |
| 362 | /// println!("oh dear"); | |
| 363 | /// } else if let Some(200) = "blarg".parse::<i32>().ok() { | |
| 364 | /// println!("uh oh"); | |
| 365 | /// } else { | |
| 366 | /// println!("phew, nothing's broken"); | |
| 367 | /// } | |
| 368 | /// ``` | |
| 369 | /// | |
| 370 | /// The above is _still_ an expression but it will always evaluate to `()`. | |
| 371 | /// | |
| 372 | /// There is possibly no limit to the number of `else` blocks that could follow an `if` expression | |
| 373 | /// however if you have several then a [`match`] expression might be preferable. | |
| 374 | /// | |
| 375 | /// Read more about control flow in the [Rust Book]. | |
| 376 | /// | |
| 377 | /// [Rust Book]: ../book/ch03-05-control-flow.html#handling-multiple-conditions-with-else-if | |
| 378 | /// [`match`]: keyword.match.html | |
| 379 | /// [`false`]: keyword.false.html | |
| 380 | /// [`if`]: keyword.if.html | |
| 381 | mod else_keyword {} | |
| 382 | ||
| 383 | #[doc(keyword = "enum")] | |
| 384 | // | |
| 385 | /// A type that can be any one of several variants. | |
| 386 | /// | |
| 387 | /// Enums in Rust are similar to those of other compiled languages like C, but have important | |
| 388 | /// differences that make them considerably more powerful. What Rust calls enums are more commonly | |
| 389 | /// known as [Algebraic Data Types][ADT] if you're coming from a functional programming background. | |
| 390 | /// The important detail is that each enum variant can have data to go along with it. | |
| 391 | /// | |
| 392 | /// ```rust | |
| 393 | /// # struct Coord; | |
| 394 | /// enum SimpleEnum { | |
| 395 | /// FirstVariant, | |
| 396 | /// SecondVariant, | |
| 397 | /// ThirdVariant, | |
| 398 | /// } | |
| 399 | /// | |
| 400 | /// enum Location { | |
| 401 | /// Unknown, | |
| 402 | /// Anonymous, | |
| 403 | /// Known(Coord), | |
| 404 | /// } | |
| 405 | /// | |
| 406 | /// enum ComplexEnum { | |
| 407 | /// Nothing, | |
| 408 | /// Something(u32), | |
| 409 | /// LotsOfThings { | |
| 410 | /// usual_struct_stuff: bool, | |
| 411 | /// blah: String, | |
| 412 | /// } | |
| 413 | /// } | |
| 414 | /// | |
| 415 | /// enum EmptyEnum { } | |
| 416 | /// ``` | |
| 417 | /// | |
| 418 | /// The first enum shown is the usual kind of enum you'd find in a C-style language. The second | |
| 419 | /// shows off a hypothetical example of something storing location data, with `Coord` being any | |
| 420 | /// other type that's needed, for example a struct. The third example demonstrates the kind of | |
| 421 | /// data a variant can store, ranging from nothing, to a tuple, to a struct-like variant. | |
| 422 | /// | |
| 423 | /// Instantiating enum variants involves explicitly using the enum's name as its namespace, | |
| 424 | /// followed by one of its variants. `SimpleEnum::SecondVariant` would be an example from above. | |
| 425 | /// When data follows along with a variant, such as with rust's built-in [`Option`] type, the data | |
| 426 | /// is added as the type describes, for example `Option::Some(123)`. The same follows with | |
| 427 | /// struct-like variants, with things looking like `ComplexEnum::LotsOfThings { usual_struct_stuff: | |
| 428 | /// true, blah: "hello!".to_string(), }`. Empty Enums are similar to [`!`] in that they cannot be | |
| 429 | /// instantiated at all, and are used mainly to mess with the type system in interesting ways. | |
| 430 | /// | |
| 431 | /// For more information, take a look at the [Rust Book] or the [Reference] | |
| 432 | /// | |
| 433 | /// [ADT]: https://en.wikipedia.org/wiki/Algebraic_data_type | |
| 434 | /// [Rust Book]: ../book/ch06-01-defining-an-enum.html | |
| 435 | /// [Reference]: ../reference/items/enumerations.html | |
| 436 | mod enum_keyword {} | |
| 437 | ||
| 438 | #[doc(keyword = "extern")] | |
| 439 | // | |
| 440 | /// Link to or import external code. | |
| 441 | /// | |
| 442 | /// The `extern` keyword is used in two places in Rust. One is in conjunction with the [`crate`] | |
| 443 | /// keyword to make your Rust code aware of other Rust crates in your project, i.e., `extern crate | |
| 444 | /// lazy_static;`. The other use is in foreign function interfaces (FFI). | |
| 445 | /// | |
| 446 | /// `extern` is used in two different contexts within FFI. The first is in the form of external | |
| 447 | /// blocks, for declaring function interfaces that Rust code can call foreign code by. This use | |
| 448 | /// of `extern` is unsafe, since we are asserting to the compiler that all function declarations | |
| 449 | /// are correct. If they are not, using these items may lead to undefined behavior. | |
| 450 | /// | |
| 451 | /// ```rust ignore | |
| 452 | /// // SAFETY: The function declarations given below are in | |
| 453 | /// // line with the header files of `my_c_library`. | |
| 454 | /// #[link(name = "my_c_library")] | |
| 455 | /// unsafe extern "C" { | |
| 456 | /// fn my_c_function(x: i32) -> bool; | |
| 457 | /// } | |
| 458 | /// ``` | |
| 459 | /// | |
| 460 | /// This code would attempt to link with `libmy_c_library.so` on unix-like systems and | |
| 461 | /// `my_c_library.dll` on Windows at runtime, and panic if it can't find something to link to. Rust | |
| 462 | /// code could then use `my_c_function` as if it were any other unsafe Rust function. Working with | |
| 463 | /// non-Rust languages and FFI is inherently unsafe, so wrappers are usually built around C APIs. | |
| 464 | /// | |
| 465 | /// The mirror use case of FFI is also done via the `extern` keyword: | |
| 466 | /// | |
| 467 | /// ```rust | |
| 468 | /// #[unsafe(no_mangle)] | |
| 469 | /// pub extern "C" fn callable_from_c(x: i32) -> bool { | |
| 470 | /// x % 3 == 0 | |
| 471 | /// } | |
| 472 | /// ``` | |
| 473 | /// | |
| 474 | /// If compiled as a dylib, the resulting .so could then be linked to from a C library, and the | |
| 475 | /// function could be used as if it was from any other library. | |
| 476 | /// | |
| 477 | /// For more information on FFI, check the [Rust book] or the [Reference]. | |
| 478 | /// | |
| 479 | /// [Rust book]: | |
| 480 | /// ../book/ch19-01-unsafe-rust.html#using-extern-functions-to-call-external-code | |
| 481 | /// [Reference]: ../reference/items/external-blocks.html | |
| 482 | /// [`crate`]: keyword.crate.html | |
| 483 | mod extern_keyword {} | |
| 484 | ||
| 485 | #[doc(keyword = "false")] | |
| 486 | // | |
| 487 | /// A value of type [`prim@bool`] representing logical **false**. | |
| 488 | /// | |
| 489 | /// `false` is the logical opposite of [`true`]. | |
| 490 | /// | |
| 491 | /// See the documentation for [`true`] for more information. | |
| 492 | /// | |
| 493 | /// [`true`]: keyword.true.html | |
| 494 | mod false_keyword {} | |
| 495 | ||
| 496 | #[doc(keyword = "fn")] | |
| 497 | // | |
| 498 | /// A function or function pointer. | |
| 499 | /// | |
| 500 | /// Functions are the primary way code is executed within Rust. Function blocks, usually just | |
| 501 | /// called functions, can be defined in a variety of different places and be assigned many | |
| 502 | /// different attributes and modifiers. | |
| 503 | /// | |
| 504 | /// Standalone functions that just sit within a module not attached to anything else are common, | |
| 505 | /// but most functions will end up being inside [`impl`] blocks, either on another type itself, or | |
| 506 | /// as a trait impl for that type. | |
| 507 | /// | |
| 508 | /// ```rust | |
| 509 | /// fn standalone_function() { | |
| 510 | /// // code | |
| 511 | /// } | |
| 512 | /// | |
| 513 | /// pub fn public_thing(argument: bool) -> String { | |
| 514 | /// // code | |
| 515 | /// # "".to_string() | |
| 516 | /// } | |
| 517 | /// | |
| 518 | /// struct Thing { | |
| 519 | /// foo: i32, | |
| 520 | /// } | |
| 521 | /// | |
| 522 | /// impl Thing { | |
| 523 | /// pub fn new() -> Self { | |
| 524 | /// Self { | |
| 525 | /// foo: 42, | |
| 526 | /// } | |
| 527 | /// } | |
| 528 | /// } | |
| 529 | /// ``` | |
| 530 | /// | |
| 531 | /// In addition to presenting fixed types in the form of `fn name(arg: type, ..) -> return_type`, | |
| 532 | /// functions can also declare a list of type parameters along with trait bounds that they fall | |
| 533 | /// into. | |
| 534 | /// | |
| 535 | /// ```rust | |
| 536 | /// fn generic_function<T: Clone>(x: T) -> (T, T, T) { | |
| 537 | /// (x.clone(), x.clone(), x.clone()) | |
| 538 | /// } | |
| 539 | /// | |
| 540 | /// fn generic_where<T>(x: T) -> T | |
| 541 | /// where T: std::ops::Add<Output = T> + Copy | |
| 542 | /// { | |
| 543 | /// x + x + x | |
| 544 | /// } | |
| 545 | /// ``` | |
| 546 | /// | |
| 547 | /// Declaring trait bounds in the angle brackets is functionally identical to using a `where` | |
| 548 | /// clause. It's up to the programmer to decide which works better in each situation, but `where` | |
| 549 | /// tends to be better when things get longer than one line. | |
| 550 | /// | |
| 551 | /// Along with being made public via `pub`, `fn` can also have an [`extern`] added for use in | |
| 552 | /// FFI. | |
| 553 | /// | |
| 554 | /// For more information on the various types of functions and how they're used, consult the [Rust | |
| 555 | /// book] or the [Reference]. | |
| 556 | /// | |
| 557 | /// [`impl`]: keyword.impl.html | |
| 558 | /// [`extern`]: keyword.extern.html | |
| 559 | /// [Rust book]: ../book/ch03-03-how-functions-work.html | |
| 560 | /// [Reference]: ../reference/items/functions.html | |
| 561 | mod fn_keyword {} | |
| 562 | ||
| 563 | #[doc(keyword = "for")] | |
| 564 | // | |
| 565 | /// Iteration with [`in`], trait implementation with [`impl`], or [higher-ranked trait bounds] | |
| 566 | /// (`for<'a>`). | |
| 567 | /// | |
| 568 | /// The `for` keyword is used in many syntactic locations: | |
| 569 | /// | |
| 570 | /// * `for` is used in for-in-loops (see below). | |
| 571 | /// * `for` is used when implementing traits as in `impl Trait for Type` (see [`impl`] for more info | |
| 572 | /// on that). | |
| 573 | /// * `for` is also used for [higher-ranked trait bounds] as in `for<'a> &'a T: PartialEq<i32>`. | |
| 574 | /// | |
| 575 | /// for-in-loops, or to be more precise, iterator loops, are a simple syntactic sugar over a common | |
| 576 | /// practice within Rust, which is to loop over anything that implements [`IntoIterator`] until the | |
| 577 | /// iterator returned by `.into_iter()` returns `None` (or the loop body uses `break`). | |
| 578 | /// | |
| 579 | /// ```rust | |
| 580 | /// for i in 0..5 { | |
| 581 | /// println!("{}", i * 2); | |
| 582 | /// } | |
| 583 | /// | |
| 584 | /// for i in std::iter::repeat(5) { | |
| 585 | /// println!("turns out {i} never stops being 5"); | |
| 586 | /// break; // would loop forever otherwise | |
| 587 | /// } | |
| 588 | /// | |
| 589 | /// 'outer: for x in 5..50 { | |
| 590 | /// for y in 0..10 { | |
| 591 | /// if x == y { | |
| 592 | /// break 'outer; | |
| 593 | /// } | |
| 594 | /// } | |
| 595 | /// } | |
| 596 | /// ``` | |
| 597 | /// | |
| 598 | /// As shown in the example above, `for` loops (along with all other loops) can be tagged, using | |
| 599 | /// similar syntax to lifetimes (only visually similar, entirely distinct in practice). Giving the | |
| 600 | /// same tag to `break` breaks the tagged loop, which is useful for inner loops. It is definitely | |
| 601 | /// not a goto. | |
| 602 | /// | |
| 603 | /// A `for` loop expands as shown: | |
| 604 | /// | |
| 605 | /// ```rust | |
| 606 | /// # fn code() { } | |
| 607 | /// # let iterator = 0..2; | |
| 608 | /// for loop_variable in iterator { | |
| 609 | /// code() | |
| 610 | /// } | |
| 611 | /// ``` | |
| 612 | /// | |
| 613 | /// ```rust | |
| 614 | /// # fn code() { } | |
| 615 | /// # let iterator = 0..2; | |
| 616 | /// { | |
| 617 | /// let result = match IntoIterator::into_iter(iterator) { | |
| 618 | /// mut iter => loop { | |
| 619 | /// match iter.next() { | |
| 620 | /// None => break, | |
| 621 | /// Some(loop_variable) => { code(); }, | |
| 622 | /// }; | |
| 623 | /// }, | |
| 624 | /// }; | |
| 625 | /// result | |
| 626 | /// } | |
| 627 | /// ``` | |
| 628 | /// | |
| 629 | /// More details on the functionality shown can be seen at the [`IntoIterator`] docs. | |
| 630 | /// | |
| 631 | /// For more information on for-loops, see the [Rust book] or the [Reference]. | |
| 632 | /// | |
| 633 | /// See also, [`loop`], [`while`]. | |
| 634 | /// | |
| 635 | /// [`in`]: keyword.in.html | |
| 636 | /// [`impl`]: keyword.impl.html | |
| 637 | /// [`loop`]: keyword.loop.html | |
| 638 | /// [`while`]: keyword.while.html | |
| 639 | /// [higher-ranked trait bounds]: ../reference/trait-bounds.html#higher-ranked-trait-bounds | |
| 640 | /// [Rust book]: | |
| 641 | /// ../book/ch03-05-control-flow.html#looping-through-a-collection-with-for | |
| 642 | /// [Reference]: ../reference/expressions/loop-expr.html#iterator-loops | |
| 643 | mod for_keyword {} | |
| 644 | ||
| 645 | #[doc(keyword = "if")] | |
| 646 | // | |
| 647 | /// Evaluate a block if a condition holds. | |
| 648 | /// | |
| 649 | /// `if` is a familiar construct to most programmers, and is the main way you'll often do logic in | |
| 650 | /// your code. However, unlike in most languages, `if` blocks can also act as expressions. | |
| 651 | /// | |
| 652 | /// ```rust | |
| 653 | /// # let rude = true; | |
| 654 | /// if 1 == 2 { | |
| 655 | /// println!("whoops, mathematics broke"); | |
| 656 | /// } else { | |
| 657 | /// println!("everything's fine!"); | |
| 658 | /// } | |
| 659 | /// | |
| 660 | /// let greeting = if rude { | |
| 661 | /// "sup nerd." | |
| 662 | /// } else { | |
| 663 | /// "hello, friend!" | |
| 664 | /// }; | |
| 665 | /// | |
| 666 | /// if let Ok(x) = "123".parse::<i32>() { | |
| 667 | /// println!("{} double that and you get {}!", greeting, x * 2); | |
| 668 | /// } | |
| 669 | /// ``` | |
| 670 | /// | |
| 671 | /// Shown above are the three typical forms an `if` block comes in. First is the usual kind of | |
| 672 | /// thing you'd see in many languages, with an optional `else` block. Second uses `if` as an | |
| 673 | /// expression, which is only possible if all branches return the same type. An `if` expression can | |
| 674 | /// be used everywhere you'd expect. The third kind of `if` block is an `if let` block, which | |
| 675 | /// behaves similarly to using a `match` expression: | |
| 676 | /// | |
| 677 | /// ```rust | |
| 678 | /// if let Some(x) = Some(123) { | |
| 679 | /// // code | |
| 680 | /// # let _ = x; | |
| 681 | /// } else { | |
| 682 | /// // something else | |
| 683 | /// } | |
| 684 | /// | |
| 685 | /// match Some(123) { | |
| 686 | /// Some(x) => { | |
| 687 | /// // code | |
| 688 | /// # let _ = x; | |
| 689 | /// }, | |
| 690 | /// _ => { | |
| 691 | /// // something else | |
| 692 | /// }, | |
| 693 | /// } | |
| 694 | /// ``` | |
| 695 | /// | |
| 696 | /// Each kind of `if` expression can be mixed and matched as needed. | |
| 697 | /// | |
| 698 | /// ```rust | |
| 699 | /// if true == false { | |
| 700 | /// println!("oh no"); | |
| 701 | /// } else if "something" == "other thing" { | |
| 702 | /// println!("oh dear"); | |
| 703 | /// } else if let Some(200) = "blarg".parse::<i32>().ok() { | |
| 704 | /// println!("uh oh"); | |
| 705 | /// } else { | |
| 706 | /// println!("phew, nothing's broken"); | |
| 707 | /// } | |
| 708 | /// ``` | |
| 709 | /// | |
| 710 | /// The `if` keyword is used in one other place in Rust, namely as a part of pattern matching | |
| 711 | /// itself, allowing patterns such as `Some(x) if x > 200` to be used. | |
| 712 | /// | |
| 713 | /// For more information on `if` expressions, see the [Rust book] or the [Reference]. | |
| 714 | /// | |
| 715 | /// [Rust book]: ../book/ch03-05-control-flow.html#if-expressions | |
| 716 | /// [Reference]: ../reference/expressions/if-expr.html | |
| 717 | mod if_keyword {} | |
| 718 | ||
| 719 | #[doc(keyword = "impl")] | |
| 720 | // | |
| 721 | /// Implementations of functionality for a type, or a type implementing some functionality. | |
| 722 | /// | |
| 723 | /// There are two uses of the keyword `impl`: | |
| 724 | /// * An `impl` block is an item that is used to implement some functionality for a type. | |
| 725 | /// * An `impl Trait` in a type-position can be used to designate a type that implements a trait called `Trait`. | |
| 726 | /// | |
| 727 | /// # Implementing Functionality for a Type | |
| 728 | /// | |
| 729 | /// The `impl` keyword is primarily used to define implementations on types. Inherent | |
| 730 | /// implementations are standalone, while trait implementations are used to implement traits for | |
| 731 | /// types, or other traits. | |
| 732 | /// | |
| 733 | /// An implementation consists of definitions of functions and consts. A function defined in an | |
| 734 | /// `impl` block can be standalone, meaning it would be called like `Vec::new()`. If the function | |
| 735 | /// takes `self`, `&self`, or `&mut self` as its first argument, it can also be called using | |
| 736 | /// method-call syntax, a familiar feature to any object-oriented programmer, like `vec.len()`. | |
| 737 | /// | |
| 738 | /// ## Inherent Implementations | |
| 739 | /// | |
| 740 | /// ```rust | |
| 741 | /// struct Example { | |
| 742 | /// number: i32, | |
| 743 | /// } | |
| 744 | /// | |
| 745 | /// impl Example { | |
| 746 | /// fn boo() { | |
| 747 | /// println!("boo! Example::boo() was called!"); | |
| 748 | /// } | |
| 749 | /// | |
| 750 | /// fn answer(&mut self) { | |
| 751 | /// self.number += 42; | |
| 752 | /// } | |
| 753 | /// | |
| 754 | /// fn get_number(&self) -> i32 { | |
| 755 | /// self.number | |
| 756 | /// } | |
| 757 | /// } | |
| 758 | /// ``` | |
| 759 | /// | |
| 760 | /// It matters little where an inherent implementation is defined; | |
| 761 | /// its functionality is in scope wherever its implementing type is. | |
| 762 | /// | |
| 763 | /// ## Trait Implementations | |
| 764 | /// | |
| 765 | /// ```rust | |
| 766 | /// struct Example { | |
| 767 | /// number: i32, | |
| 768 | /// } | |
| 769 | /// | |
| 770 | /// trait Thingy { | |
| 771 | /// fn do_thingy(&self); | |
| 772 | /// } | |
| 773 | /// | |
| 774 | /// impl Thingy for Example { | |
| 775 | /// fn do_thingy(&self) { | |
| 776 | /// println!("doing a thing! also, number is {}!", self.number); | |
| 777 | /// } | |
| 778 | /// } | |
| 779 | /// ``` | |
| 780 | /// | |
| 781 | /// It matters little where a trait implementation is defined; | |
| 782 | /// its functionality can be brought into scope by importing the trait it implements. | |
| 783 | /// | |
| 784 | /// For more information on implementations, see the [Rust book][book1] or the [Reference]. | |
| 785 | /// | |
| 786 | /// # Designating a Type that Implements Some Functionality | |
| 787 | /// | |
| 788 | /// The other use of the `impl` keyword is in `impl Trait` syntax, which can be understood to mean | |
| 789 | /// "any (or some) concrete type that implements Trait". | |
| 790 | /// It can be used as the type of a variable declaration, | |
| 791 | /// in [argument position](https://rust-lang.github.io/rfcs/1951-expand-impl-trait.html) | |
| 792 | /// or in [return position](https://rust-lang.github.io/rfcs/3425-return-position-impl-trait-in-traits.html). | |
| 793 | /// One pertinent use case is in working with closures, which have unnameable types. | |
| 794 | /// | |
| 795 | /// ```rust | |
| 796 | /// fn thing_returning_closure() -> impl Fn(i32) -> bool { | |
| 797 | /// println!("here's a closure for you!"); | |
| 798 | /// |x: i32| x % 3 == 0 | |
| 799 | /// } | |
| 800 | /// ``` | |
| 801 | /// | |
| 802 | /// For more information on `impl Trait` syntax, see the [Rust book][book2]. | |
| 803 | /// | |
| 804 | /// [book1]: ../book/ch05-03-method-syntax.html | |
| 805 | /// [Reference]: ../reference/items/implementations.html | |
| 806 | /// [book2]: ../book/ch10-02-traits.html#returning-types-that-implement-traits | |
| 807 | mod impl_keyword {} | |
| 808 | ||
| 809 | #[doc(keyword = "in")] | |
| 810 | // | |
| 811 | /// Iterate over a series of values with [`for`]. | |
| 812 | /// | |
| 813 | /// The expression immediately following `in` must implement the [`IntoIterator`] trait. | |
| 814 | /// | |
| 815 | /// ## Literal Examples: | |
| 816 | /// | |
| 817 | /// * `for _ in 1..3 {}` - Iterate over an exclusive range up to but excluding 3. | |
| 818 | /// * `for _ in 1..=3 {}` - Iterate over an inclusive range up to and including 3. | |
| 819 | /// | |
| 820 | /// (Read more about [range patterns]) | |
| 821 | /// | |
| 822 | /// [`IntoIterator`]: ../book/ch13-04-performance.html | |
| 823 | /// [range patterns]: ../reference/patterns.html?highlight=range#range-patterns | |
| 824 | /// [`for`]: keyword.for.html | |
| 825 | /// | |
| 826 | /// The other use of `in` is with the keyword `pub`. It allows users to declare an item as visible | |
| 827 | /// only within a given scope. | |
| 828 | /// | |
| 829 | /// ## Literal Example: | |
| 830 | /// | |
| 831 | /// * `pub(in crate::outer_mod) fn outer_mod_visible_fn() {}` - fn is visible in `outer_mod` | |
| 832 | /// | |
| 833 | /// Starting with the 2018 edition, paths for `pub(in path)` must start with `crate`, `self` or | |
| 834 | /// `super`. The 2015 edition may also use paths starting with `::` or modules from the crate root. | |
| 835 | /// | |
| 836 | /// For more information, see the [Reference]. | |
| 837 | /// | |
| 838 | /// [Reference]: ../reference/visibility-and-privacy.html#pubin-path-pubcrate-pubsuper-and-pubself | |
| 839 | mod in_keyword {} | |
| 840 | ||
| 841 | #[doc(keyword = "let")] | |
| 842 | // | |
| 843 | /// Bind a value to a variable. | |
| 844 | /// | |
| 845 | /// The primary use for the `let` keyword is in `let` statements, which are used to introduce a new | |
| 846 | /// set of variables into the current scope, as given by a pattern. | |
| 847 | /// | |
| 848 | /// ```rust | |
| 849 | /// # #![allow(unused_assignments)] | |
| 850 | /// let thing1: i32 = 100; | |
| 851 | /// let thing2 = 200 + thing1; | |
| 852 | /// | |
| 853 | /// let mut changing_thing = true; | |
| 854 | /// changing_thing = false; | |
| 855 | /// | |
| 856 | /// let (part1, part2) = ("first", "second"); | |
| 857 | /// | |
| 858 | /// struct Example { | |
| 859 | /// a: bool, | |
| 860 | /// b: u64, | |
| 861 | /// } | |
| 862 | /// | |
| 863 | /// let Example { a, b: _ } = Example { | |
| 864 | /// a: true, | |
| 865 | /// b: 10004, | |
| 866 | /// }; | |
| 867 | /// assert!(a); | |
| 868 | /// ``` | |
| 869 | /// | |
| 870 | /// The pattern is most commonly a single variable, which means no pattern matching is done and | |
| 871 | /// the expression given is bound to the variable. Apart from that, patterns used in `let` bindings | |
| 872 | /// can be as complicated as needed, given that the pattern is exhaustive. See the [Rust | |
| 873 | /// book][book1] for more information on pattern matching. The type of the pattern is optionally | |
| 874 | /// given afterwards, but if left blank is automatically inferred by the compiler if possible. | |
| 875 | /// | |
| 876 | /// Variables in Rust are immutable by default, and require the `mut` keyword to be made mutable. | |
| 877 | /// | |
| 878 | /// Multiple variables can be defined with the same name, known as shadowing. This doesn't affect | |
| 879 | /// the original variable in any way beyond being unable to directly access it beyond the point of | |
| 880 | /// shadowing. It continues to remain in scope, getting dropped only when it falls out of scope. | |
| 881 | /// Shadowed variables don't need to have the same type as the variables shadowing them. | |
| 882 | /// | |
| 883 | /// ```rust | |
| 884 | /// let shadowing_example = true; | |
| 885 | /// let shadowing_example = 123.4; | |
| 886 | /// let shadowing_example = shadowing_example as u32; | |
| 887 | /// let mut shadowing_example = format!("cool! {shadowing_example}"); | |
| 888 | /// shadowing_example += " something else!"; // not shadowing | |
| 889 | /// ``` | |
| 890 | /// | |
| 891 | /// Other places the `let` keyword is used include along with [`if`], in the form of `if let` | |
| 892 | /// expressions. They're useful if the pattern being matched isn't exhaustive, such as with | |
| 893 | /// enumerations. `while let` also exists, which runs a loop with a pattern matched value until | |
| 894 | /// that pattern can't be matched. | |
| 895 | /// | |
| 896 | /// For more information on the `let` keyword, see the [Rust book][book2] or the [Reference] | |
| 897 | /// | |
| 898 | /// [book1]: ../book/ch06-02-match.html | |
| 899 | /// [`if`]: keyword.if.html | |
| 900 | /// [book2]: ../book/ch18-01-all-the-places-for-patterns.html#let-statements | |
| 901 | /// [Reference]: ../reference/statements.html#let-statements | |
| 902 | mod let_keyword {} | |
| 903 | ||
| 904 | #[doc(keyword = "loop")] | |
| 905 | // | |
| 906 | /// Loop indefinitely. | |
| 907 | /// | |
| 908 | /// `loop` is used to define the simplest kind of loop supported in Rust. It runs the code inside | |
| 909 | /// it until the code uses `break` or the program exits. | |
| 910 | /// | |
| 911 | /// ```rust | |
| 912 | /// loop { | |
| 913 | /// println!("hello world forever!"); | |
| 914 | /// # break; | |
| 915 | /// } | |
| 916 | /// | |
| 917 | /// let mut i = 1; | |
| 918 | /// loop { | |
| 919 | /// println!("i is {i}"); | |
| 920 | /// if i > 100 { | |
| 921 | /// break; | |
| 922 | /// } | |
| 923 | /// i *= 2; | |
| 924 | /// } | |
| 925 | /// assert_eq!(i, 128); | |
| 926 | /// ``` | |
| 927 | /// | |
| 928 | /// Unlike the other kinds of loops in Rust (`while`, `while let`, and `for`), loops can be used as | |
| 929 | /// expressions that return values via `break`. | |
| 930 | /// | |
| 931 | /// ```rust | |
| 932 | /// let mut i = 1; | |
| 933 | /// let something = loop { | |
| 934 | /// i *= 2; | |
| 935 | /// if i > 100 { | |
| 936 | /// break i; | |
| 937 | /// } | |
| 938 | /// }; | |
| 939 | /// assert_eq!(something, 128); | |
| 940 | /// ``` | |
| 941 | /// | |
| 942 | /// Every `break` in a loop has to have the same type. When it's not explicitly giving something, | |
| 943 | /// `break;` returns `()`. | |
| 944 | /// | |
| 945 | /// For more information on `loop` and loops in general, see the [Reference]. | |
| 946 | /// | |
| 947 | /// See also, [`for`], [`while`]. | |
| 948 | /// | |
| 949 | /// [`for`]: keyword.for.html | |
| 950 | /// [`while`]: keyword.while.html | |
| 951 | /// [Reference]: ../reference/expressions/loop-expr.html | |
| 952 | mod loop_keyword {} | |
| 953 | ||
| 954 | #[doc(keyword = "match")] | |
| 955 | // | |
| 956 | /// Control flow based on pattern matching. | |
| 957 | /// | |
| 958 | /// `match` can be used to run code conditionally. Every pattern must | |
| 959 | /// be handled exhaustively either explicitly or by using wildcards like | |
| 960 | /// `_` in the `match`. Since `match` is an expression, values can also be | |
| 961 | /// returned. | |
| 962 | /// | |
| 963 | /// ```rust | |
| 964 | /// let opt: Option<usize> = None; | |
| 965 | /// let x = match opt { | |
| 966 | /// Some(int) => int, | |
| 967 | /// None => 10, | |
| 968 | /// }; | |
| 969 | /// assert_eq!(x, 10); | |
| 970 | /// | |
| 971 | /// let a_number = Some(10); | |
| 972 | /// match a_number { | |
| 973 | /// Some(x) if x <= 5 => println!("0 to 5 num = {x}"), | |
| 974 | /// Some(x @ 6..=10) => println!("6 to 10 num = {x}"), | |
| 975 | /// None => panic!(), | |
| 976 | /// // all other numbers | |
| 977 | /// _ => panic!(), | |
| 978 | /// } | |
| 979 | /// ``` | |
| 980 | /// | |
| 981 | /// `match` can be used to gain access to the inner members of an enum | |
| 982 | /// and use them directly. | |
| 983 | /// | |
| 984 | /// ```rust | |
| 985 | /// enum Outer { | |
| 986 | /// Double(Option<u8>, Option<String>), | |
| 987 | /// Single(Option<u8>), | |
| 988 | /// Empty | |
| 989 | /// } | |
| 990 | /// | |
| 991 | /// let get_inner = Outer::Double(None, Some(String::new())); | |
| 992 | /// match get_inner { | |
| 993 | /// Outer::Double(None, Some(st)) => println!("{st}"), | |
| 994 | /// Outer::Single(opt) => println!("{opt:?}"), | |
| 995 | /// _ => panic!(), | |
| 996 | /// } | |
| 997 | /// ``` | |
| 998 | /// | |
| 999 | /// For more information on `match` and matching in general, see the [Reference]. | |
| 1000 | /// | |
| 1001 | /// [Reference]: ../reference/expressions/match-expr.html | |
| 1002 | mod match_keyword {} | |
| 1003 | ||
| 1004 | #[doc(keyword = "mod")] | |
| 1005 | // | |
| 1006 | /// Organize code into [modules]. | |
| 1007 | /// | |
| 1008 | /// Use `mod` to create new [modules] to encapsulate code, including other | |
| 1009 | /// modules: | |
| 1010 | /// | |
| 1011 | /// ``` | |
| 1012 | /// mod foo { | |
| 1013 | /// mod bar { | |
| 1014 | /// type MyType = (u8, u8); | |
| 1015 | /// fn baz() {} | |
| 1016 | /// } | |
| 1017 | /// } | |
| 1018 | /// ``` | |
| 1019 | /// | |
| 1020 | /// Like [`struct`]s and [`enum`]s, a module and its content are private by | |
| 1021 | /// default, inaccessible to code outside of the module. | |
| 1022 | /// | |
| 1023 | /// To learn more about allowing access, see the documentation for the [`pub`] | |
| 1024 | /// keyword. | |
| 1025 | /// | |
| 1026 | /// [`enum`]: keyword.enum.html | |
| 1027 | /// [`pub`]: keyword.pub.html | |
| 1028 | /// [`struct`]: keyword.struct.html | |
| 1029 | /// [modules]: ../reference/items/modules.html | |
| 1030 | mod mod_keyword {} | |
| 1031 | ||
| 1032 | #[doc(keyword = "move")] | |
| 1033 | // | |
| 1034 | /// Capture a [closure]'s environment by value. | |
| 1035 | /// | |
| 1036 | /// `move` converts any variables captured by reference or mutable reference | |
| 1037 | /// to variables captured by value. | |
| 1038 | /// | |
| 1039 | /// ```rust | |
| 1040 | /// let data = vec![1, 2, 3]; | |
| 1041 | /// let closure = move || println!("captured {data:?} by value"); | |
| 1042 | /// | |
| 1043 | /// // data is no longer available, it is owned by the closure | |
| 1044 | /// ``` | |
| 1045 | /// | |
| 1046 | /// Note: `move` closures may still implement [`Fn`] or [`FnMut`], even though | |
| 1047 | /// they capture variables by `move`. This is because the traits implemented by | |
| 1048 | /// a closure type are determined by *what* the closure does with captured | |
| 1049 | /// values, not *how* it captures them: | |
| 1050 | /// | |
| 1051 | /// ```rust | |
| 1052 | /// fn create_fn() -> impl Fn() { | |
| 1053 | /// let text = "Fn".to_owned(); | |
| 1054 | /// move || println!("This is a: {text}") | |
| 1055 | /// } | |
| 1056 | /// | |
| 1057 | /// let fn_plain = create_fn(); | |
| 1058 | /// fn_plain(); | |
| 1059 | /// ``` | |
| 1060 | /// | |
| 1061 | /// `move` is often used when [threads] are involved. | |
| 1062 | /// | |
| 1063 | #[cfg_attr(target_os = "wasi", doc = "```rust,ignore (thread::spawn not supported)")] | |
| 1064 | #[cfg_attr(not(target_os = "wasi"), doc = "```rust")] | |
| 1065 | /// let data = vec![1, 2, 3]; | |
| 1066 | /// | |
| 1067 | /// std::thread::spawn(move || { | |
| 1068 | /// println!("captured {data:?} by value") | |
| 1069 | /// }).join().unwrap(); | |
| 1070 | /// | |
| 1071 | /// // data was moved to the spawned thread, so we cannot use it here | |
| 1072 | /// ``` | |
| 1073 | /// | |
| 1074 | /// `move` is also valid before an async block. | |
| 1075 | /// | |
| 1076 | /// ```rust | |
| 1077 | /// let capture = "hello".to_owned(); | |
| 1078 | /// let block = async move { | |
| 1079 | /// println!("rust says {capture} from async block"); | |
| 1080 | /// }; | |
| 1081 | /// ``` | |
| 1082 | /// | |
| 1083 | /// For more information on the `move` keyword, see the [closures][closure] section | |
| 1084 | /// of the Rust book or the [threads] section. | |
| 1085 | /// | |
| 1086 | /// [closure]: ../book/ch13-01-closures.html | |
| 1087 | /// [threads]: ../book/ch16-01-threads.html#using-move-closures-with-threads | |
| 1088 | mod move_keyword {} | |
| 1089 | ||
| 1090 | #[doc(keyword = "mut")] | |
| 1091 | // | |
| 1092 | /// A mutable variable, reference, or pointer. | |
| 1093 | /// | |
| 1094 | /// `mut` can be used in several situations. The first is mutable variables, | |
| 1095 | /// which can be used anywhere you can bind a value to a variable name. Some | |
| 1096 | /// examples: | |
| 1097 | /// | |
| 1098 | /// ```rust | |
| 1099 | /// // A mutable variable in the parameter list of a function. | |
| 1100 | /// fn foo(mut x: u8, y: u8) -> u8 { | |
| 1101 | /// x += y; | |
| 1102 | /// x | |
| 1103 | /// } | |
| 1104 | /// | |
| 1105 | /// // Modifying a mutable variable. | |
| 1106 | /// # #[allow(unused_assignments)] | |
| 1107 | /// let mut a = 5; | |
| 1108 | /// a = 6; | |
| 1109 | /// | |
| 1110 | /// assert_eq!(foo(3, 4), 7); | |
| 1111 | /// assert_eq!(a, 6); | |
| 1112 | /// ``` | |
| 1113 | /// | |
| 1114 | /// The second is mutable references. They can be created from `mut` variables | |
| 1115 | /// and must be unique: no other variables can have a mutable reference, nor a | |
| 1116 | /// shared reference. | |
| 1117 | /// | |
| 1118 | /// ```rust | |
| 1119 | /// // Taking a mutable reference. | |
| 1120 | /// fn push_two(v: &mut Vec<u8>) { | |
| 1121 | /// v.push(2); | |
| 1122 | /// } | |
| 1123 | /// | |
| 1124 | /// // A mutable reference cannot be taken to a non-mutable variable. | |
| 1125 | /// let mut v = vec![0, 1]; | |
| 1126 | /// // Passing a mutable reference. | |
| 1127 | /// push_two(&mut v); | |
| 1128 | /// | |
| 1129 | /// assert_eq!(v, vec![0, 1, 2]); | |
| 1130 | /// ``` | |
| 1131 | /// | |
| 1132 | /// ```rust,compile_fail,E0502 | |
| 1133 | /// let mut v = vec![0, 1]; | |
| 1134 | /// let mut_ref_v = &mut v; | |
| 1135 | /// # #[allow(unused)] | |
| 1136 | /// let ref_v = &v; | |
| 1137 | /// mut_ref_v.push(2); | |
| 1138 | /// ``` | |
| 1139 | /// | |
| 1140 | /// Mutable raw pointers work much like mutable references, with the added | |
| 1141 | /// possibility of not pointing to a valid object. The syntax is `*mut Type`. | |
| 1142 | /// | |
| 1143 | /// More information on mutable references and pointers can be found in the [Reference]. | |
| 1144 | /// | |
| 1145 | /// [Reference]: ../reference/types/pointer.html#mutable-references-mut | |
| 1146 | mod mut_keyword {} | |
| 1147 | ||
| 1148 | #[doc(keyword = "pub")] | |
| 1149 | // | |
| 1150 | /// Make an item visible to others. | |
| 1151 | /// | |
| 1152 | /// The keyword `pub` makes any module, function, or data structure accessible from inside | |
| 1153 | /// of external modules. The `pub` keyword may also be used in a `use` declaration to re-export | |
| 1154 | /// an identifier from a namespace. | |
| 1155 | /// | |
| 1156 | /// For more information on the `pub` keyword, please see the visibility section | |
| 1157 | /// of the [reference] and for some examples, see [Rust by Example]. | |
| 1158 | /// | |
| 1159 | /// [reference]:../reference/visibility-and-privacy.html?highlight=pub#visibility-and-privacy | |
| 1160 | /// [Rust by Example]:../rust-by-example/mod/visibility.html | |
| 1161 | mod pub_keyword {} | |
| 1162 | ||
| 1163 | #[doc(keyword = "ref")] | |
| 1164 | // | |
| 1165 | /// Bind by reference during pattern matching. | |
| 1166 | /// | |
| 1167 | /// `ref` annotates pattern bindings to make them borrow rather than move. | |
| 1168 | /// It is **not** a part of the pattern as far as matching is concerned: it does | |
| 1169 | /// not affect *whether* a value is matched, only *how* it is matched. | |
| 1170 | /// | |
| 1171 | /// By default, [`match`] statements consume all they can, which can sometimes | |
| 1172 | /// be a problem, when you don't really need the value to be moved and owned: | |
| 1173 | /// | |
| 1174 | /// ```compile_fail,E0382 | |
| 1175 | /// let maybe_name = Some(String::from("Alice")); | |
| 1176 | /// // The variable 'maybe_name' is consumed here ... | |
| 1177 | /// match maybe_name { | |
| 1178 | /// Some(n) => println!("Hello, {n}"), | |
| 1179 | /// _ => println!("Hello, world"), | |
| 1180 | /// } | |
| 1181 | /// // ... and is now unavailable. | |
| 1182 | /// println!("Hello again, {}", maybe_name.unwrap_or("world".into())); | |
| 1183 | /// ``` | |
| 1184 | /// | |
| 1185 | /// Using the `ref` keyword, the value is only borrowed, not moved, making it | |
| 1186 | /// available for use after the [`match`] statement: | |
| 1187 | /// | |
| 1188 | /// ``` | |
| 1189 | /// let maybe_name = Some(String::from("Alice")); | |
| 1190 | /// // Using `ref`, the value is borrowed, not moved ... | |
| 1191 | /// match maybe_name { | |
| 1192 | /// Some(ref n) => println!("Hello, {n}"), | |
| 1193 | /// _ => println!("Hello, world"), | |
| 1194 | /// } | |
| 1195 | /// // ... so it's available here! | |
| 1196 | /// println!("Hello again, {}", maybe_name.unwrap_or("world".into())); | |
| 1197 | /// ``` | |
| 1198 | /// | |
| 1199 | /// # `&` vs `ref` | |
| 1200 | /// | |
| 1201 | /// - `&` denotes that your pattern expects a reference to an object. Hence `&` | |
| 1202 | /// is a part of said pattern: `&Foo` matches different objects than `Foo` does. | |
| 1203 | /// | |
| 1204 | /// - `ref` indicates that you want a reference to an unpacked value. It is not | |
| 1205 | /// matched against: `Foo(ref foo)` matches the same objects as `Foo(foo)`. | |
| 1206 | /// | |
| 1207 | /// See also the [Reference] for more information. | |
| 1208 | /// | |
| 1209 | /// [`match`]: keyword.match.html | |
| 1210 | /// [Reference]: ../reference/patterns.html#identifier-patterns | |
| 1211 | mod ref_keyword {} | |
| 1212 | ||
| 1213 | #[doc(keyword = "return")] | |
| 1214 | // | |
| 1215 | /// Returns a value from a function. | |
| 1216 | /// | |
| 1217 | /// A `return` marks the end of an execution path in a function: | |
| 1218 | /// | |
| 1219 | /// ``` | |
| 1220 | /// fn foo() -> i32 { | |
| 1221 | /// return 3; | |
| 1222 | /// } | |
| 1223 | /// assert_eq!(foo(), 3); | |
| 1224 | /// ``` | |
| 1225 | /// | |
| 1226 | /// `return` is not needed when the returned value is the last expression in the | |
| 1227 | /// function. In this case the `;` is omitted: | |
| 1228 | /// | |
| 1229 | /// ``` | |
| 1230 | /// fn foo() -> i32 { | |
| 1231 | /// 3 | |
| 1232 | /// } | |
| 1233 | /// assert_eq!(foo(), 3); | |
| 1234 | /// ``` | |
| 1235 | /// | |
| 1236 | /// `return` returns from the function immediately (an "early return"): | |
| 1237 | /// | |
| 1238 | /// ```no_run | |
| 1239 | /// fn main() -> Result<(), &'static str> { | |
| 1240 | /// let contents = "Hello, world!"; | |
| 1241 | /// | |
| 1242 | /// if contents.contains("impossible!") { | |
| 1243 | /// return Err("oh no!"); | |
| 1244 | /// } | |
| 1245 | /// | |
| 1246 | /// if contents.len() > 9000 { | |
| 1247 | /// return Err("over 9000!"); | |
| 1248 | /// } | |
| 1249 | /// | |
| 1250 | /// Ok(()) | |
| 1251 | /// } | |
| 1252 | /// ``` | |
| 1253 | /// | |
| 1254 | /// Within [closures] and [`async`] blocks, `return` returns a value from within the closure or | |
| 1255 | /// `async` block, not from the parent function: | |
| 1256 | /// | |
| 1257 | /// ```rust | |
| 1258 | /// fn foo() -> i32 { | |
| 1259 | /// let closure = || { | |
| 1260 | /// return 5; | |
| 1261 | /// }; | |
| 1262 | /// | |
| 1263 | /// let future = async { | |
| 1264 | /// return 10; | |
| 1265 | /// }; | |
| 1266 | /// | |
| 1267 | /// return 15; | |
| 1268 | /// } | |
| 1269 | /// | |
| 1270 | /// assert_eq!(foo(), 15); | |
| 1271 | /// ``` | |
| 1272 | /// | |
| 1273 | /// [closures]: ../book/ch13-01-closures.html | |
| 1274 | /// [`async`]: ../std/keyword.async.html | |
| 1275 | mod return_keyword {} | |
| 1276 | ||
| 1277 | #[doc(keyword = "become")] | |
| 1278 | // | |
| 1279 | /// Perform a tail-call of a function. | |
| 1280 | /// | |
| 1281 | /// <div class="warning"> | |
| 1282 | /// | |
| 1283 | /// `feature(explicit_tail_calls)` is currently incomplete and may not work properly. | |
| 1284 | /// </div> | |
| 1285 | /// | |
| 1286 | /// When tail calling a function, instead of its stack frame being added to the | |
| 1287 | /// stack, the stack frame of the caller is directly replaced with the callee's. | |
| 1288 | /// This means that as long as a loop in a call graph only uses tail calls, the | |
| 1289 | /// stack growth will be bounded. | |
| 1290 | /// | |
| 1291 | /// This is useful for writing functional-style code (since it prevents recursion | |
| 1292 | /// from exhausting resources) or for code optimization (since a tail call | |
| 1293 | /// *might* be cheaper than a normal call, tail calls can be used in a similar | |
| 1294 | /// manner to computed goto). | |
| 1295 | /// | |
| 1296 | /// Example of using `become` to implement functional-style `fold`: | |
| 1297 | /// | |
| 1298 | /// ```ignore-wasm (tail-call target feature not enabled by default on wasm) | |
| 1299 | /// #![feature(explicit_tail_calls)] | |
| 1300 | /// #![expect(incomplete_features)] | |
| 1301 | /// | |
| 1302 | /// fn fold<T: Copy, S>(slice: &[T], init: S, f: impl Fn(S, T) -> S) -> S { | |
| 1303 | /// match slice { | |
| 1304 | /// // without `become`, on big inputs this could easily overflow the | |
| 1305 | /// // stack. using a tail call guarantees that the stack will not grow unboundedly | |
| 1306 | /// [first, rest @ ..] => become fold(rest, f(init, *first), f), | |
| 1307 | /// [] => init, | |
| 1308 | /// } | |
| 1309 | /// } | |
| 1310 | /// ``` | |
| 1311 | /// | |
| 1312 | /// Compilers can already perform "tail call optimization" -- they can replace normal | |
| 1313 | /// calls with tail calls, although there are no guarantees that this will be done. | |
| 1314 | /// However, to perform TCO, the call needs to be the last thing that happens | |
| 1315 | /// in the functions and be returned from it. This requirement is often broken | |
| 1316 | /// by drop code for locals, which is run after computing the return expression: | |
| 1317 | /// | |
| 1318 | /// ``` | |
| 1319 | /// fn example() { | |
| 1320 | /// let string = "meow".to_owned(); | |
| 1321 | /// println!("{string}"); | |
| 1322 | /// return help(); // this is *not* the last thing that happens in `example`... | |
| 1323 | /// } | |
| 1324 | /// | |
| 1325 | /// // ... because it is desugared to this: | |
| 1326 | /// fn example_desugared() { | |
| 1327 | /// let string = "meow".to_owned(); | |
| 1328 | /// println!("{string}"); | |
| 1329 | /// let tmp = help(); | |
| 1330 | /// drop(string); | |
| 1331 | /// return tmp; | |
| 1332 | /// } | |
| 1333 | /// | |
| 1334 | /// fn help() {} | |
| 1335 | /// ``` | |
| 1336 | /// | |
| 1337 | /// For this reason, `become` also changes the drop order, such that locals are | |
| 1338 | /// dropped *before* evaluating the call. | |
| 1339 | /// | |
| 1340 | /// In order to guarantee that the compiler can perform a tail call, `become` | |
| 1341 | /// currently has these requirements: | |
| 1342 | /// 1. callee and caller must have the same ABI, arguments, and return type | |
| 1343 | /// 2. callee and caller must not have varargs | |
| 1344 | /// 3. caller must not be marked with `#[track_caller]` | |
| 1345 | /// - callee is allowed to be marked with `#[track_caller]` as otherwise | |
| 1346 | /// adding `#[track_caller]` would be a breaking change. if callee is | |
| 1347 | /// marked with `#[track_caller]` a tail call is not guaranteed. | |
| 1348 | /// 4. callee and caller cannot be a closure | |
| 1349 | /// (unless it's coerced to a function pointer) | |
| 1350 | /// | |
| 1351 | /// It is possible to tail-call a function pointer: | |
| 1352 | /// | |
| 1353 | /// ```ignore-wasm (tail-call target feature not enabled by default on wasm) | |
| 1354 | /// #![feature(explicit_tail_calls)] | |
| 1355 | /// #![expect(incomplete_features)] | |
| 1356 | /// | |
| 1357 | /// #[derive(Copy, Clone)] | |
| 1358 | /// enum Inst { Inc, Dec } | |
| 1359 | /// | |
| 1360 | /// fn dispatch(stream: &[Inst], state: u32) -> u32 { | |
| 1361 | /// const TABLE: &[fn(&[Inst], u32) -> u32] = &[increment, decrement]; | |
| 1362 | /// match stream { | |
| 1363 | /// [inst, rest @ ..] => become TABLE[*inst as usize](rest, state), | |
| 1364 | /// [] => state, | |
| 1365 | /// } | |
| 1366 | /// } | |
| 1367 | /// | |
| 1368 | /// fn increment(stream: &[Inst], state: u32) -> u32 { | |
| 1369 | /// become dispatch(stream, state + 1) | |
| 1370 | /// } | |
| 1371 | /// | |
| 1372 | /// fn decrement(stream: &[Inst], state: u32) -> u32 { | |
| 1373 | /// become dispatch(stream, state - 1) | |
| 1374 | /// } | |
| 1375 | /// | |
| 1376 | /// let program = &[Inst::Inc, Inst::Inc, Inst::Dec, Inst::Inc]; | |
| 1377 | /// assert_eq!(dispatch(program, 0), 2); | |
| 1378 | /// ``` | |
| 1379 | mod become_keyword {} | |
| 1380 | ||
| 1381 | #[doc(keyword = "self")] | |
| 1382 | // | |
| 1383 | /// The receiver of a method, or the current module. | |
| 1384 | /// | |
| 1385 | /// `self` is used in two situations: referencing the current module and marking | |
| 1386 | /// the receiver of a method. | |
| 1387 | /// | |
| 1388 | /// In paths, `self` can be used to refer to the current module, either in a | |
| 1389 | /// [`use`] statement or in a path to access an element: | |
| 1390 | /// | |
| 1391 | /// ``` | |
| 1392 | /// # #![allow(unused_imports)] | |
| 1393 | /// use std::io::{self, Read}; | |
| 1394 | /// ``` | |
| 1395 | /// | |
| 1396 | /// Is functionally the same as: | |
| 1397 | /// | |
| 1398 | /// ``` | |
| 1399 | /// # #![allow(unused_imports)] | |
| 1400 | /// use std::io; | |
| 1401 | /// use std::io::Read; | |
| 1402 | /// ``` | |
| 1403 | /// | |
| 1404 | /// Using `self` to access an element in the current module: | |
| 1405 | /// | |
| 1406 | /// ``` | |
| 1407 | /// # #![allow(dead_code)] | |
| 1408 | /// # fn main() {} | |
| 1409 | /// fn foo() {} | |
| 1410 | /// fn bar() { | |
| 1411 | /// self::foo() | |
| 1412 | /// } | |
| 1413 | /// ``` | |
| 1414 | /// | |
| 1415 | /// `self` as the current receiver for a method allows to omit the parameter | |
| 1416 | /// type most of the time. With the exception of this particularity, `self` is | |
| 1417 | /// used much like any other parameter: | |
| 1418 | /// | |
| 1419 | /// ``` | |
| 1420 | /// struct Foo(i32); | |
| 1421 | /// | |
| 1422 | /// impl Foo { | |
| 1423 | /// // No `self`. | |
| 1424 | /// fn new() -> Self { | |
| 1425 | /// Self(0) | |
| 1426 | /// } | |
| 1427 | /// | |
| 1428 | /// // Consuming `self`. | |
| 1429 | /// fn consume(self) -> Self { | |
| 1430 | /// Self(self.0 + 1) | |
| 1431 | /// } | |
| 1432 | /// | |
| 1433 | /// // Borrowing `self`. | |
| 1434 | /// fn borrow(&self) -> &i32 { | |
| 1435 | /// &self.0 | |
| 1436 | /// } | |
| 1437 | /// | |
| 1438 | /// // Borrowing `self` mutably. | |
| 1439 | /// fn borrow_mut(&mut self) -> &mut i32 { | |
| 1440 | /// &mut self.0 | |
| 1441 | /// } | |
| 1442 | /// } | |
| 1443 | /// | |
| 1444 | /// // This method must be called with a `Type::` prefix. | |
| 1445 | /// let foo = Foo::new(); | |
| 1446 | /// assert_eq!(foo.0, 0); | |
| 1447 | /// | |
| 1448 | /// // Those two calls produces the same result. | |
| 1449 | /// let foo = Foo::consume(foo); | |
| 1450 | /// assert_eq!(foo.0, 1); | |
| 1451 | /// let foo = foo.consume(); | |
| 1452 | /// assert_eq!(foo.0, 2); | |
| 1453 | /// | |
| 1454 | /// // Borrowing is handled automatically with the second syntax. | |
| 1455 | /// let borrow_1 = Foo::borrow(&foo); | |
| 1456 | /// let borrow_2 = foo.borrow(); | |
| 1457 | /// assert_eq!(borrow_1, borrow_2); | |
| 1458 | /// | |
| 1459 | /// // Borrowing mutably is handled automatically too with the second syntax. | |
| 1460 | /// let mut foo = Foo::new(); | |
| 1461 | /// *Foo::borrow_mut(&mut foo) += 1; | |
| 1462 | /// assert_eq!(foo.0, 1); | |
| 1463 | /// *foo.borrow_mut() += 1; | |
| 1464 | /// assert_eq!(foo.0, 2); | |
| 1465 | /// ``` | |
| 1466 | /// | |
| 1467 | /// Note that this automatic conversion when calling `foo.method()` is not | |
| 1468 | /// limited to the examples above. See the [Reference] for more information. | |
| 1469 | /// | |
| 1470 | /// [`use`]: keyword.use.html | |
| 1471 | /// [Reference]: ../reference/items/associated-items.html#methods | |
| 1472 | mod self_keyword {} | |
| 1473 | ||
| 1474 | // FIXME: Once rustdoc can handle URL conflicts on case insensitive file systems, we can replace | |
| 1475 | // these two lines with `#[doc(keyword = "Self")]` and update `is_doc_keyword` in | |
| 1476 | // `CheckAttrVisitor`. | |
| 1477 | #[doc(alias = "Self")] | |
| 1478 | #[doc(keyword = "SelfTy")] | |
| 1479 | // | |
| 1480 | /// The implementing type within a [`trait`] or [`impl`] block, or the current type within a type | |
| 1481 | /// definition. | |
| 1482 | /// | |
| 1483 | /// Within a type definition: | |
| 1484 | /// | |
| 1485 | /// ``` | |
| 1486 | /// # #![allow(dead_code)] | |
| 1487 | /// struct Node { | |
| 1488 | /// elem: i32, | |
| 1489 | /// // `Self` is a `Node` here. | |
| 1490 | /// next: Option<Box<Self>>, | |
| 1491 | /// } | |
| 1492 | /// ``` | |
| 1493 | /// | |
| 1494 | /// In an [`impl`] block: | |
| 1495 | /// | |
| 1496 | /// ``` | |
| 1497 | /// struct Foo(i32); | |
| 1498 | /// | |
| 1499 | /// impl Foo { | |
| 1500 | /// fn new() -> Self { | |
| 1501 | /// Self(0) | |
| 1502 | /// } | |
| 1503 | /// } | |
| 1504 | /// | |
| 1505 | /// assert_eq!(Foo::new().0, Foo(0).0); | |
| 1506 | /// ``` | |
| 1507 | /// | |
| 1508 | /// Generic parameters are implicit with `Self`: | |
| 1509 | /// | |
| 1510 | /// ``` | |
| 1511 | /// # #![allow(dead_code)] | |
| 1512 | /// struct Wrap<T> { | |
| 1513 | /// elem: T, | |
| 1514 | /// } | |
| 1515 | /// | |
| 1516 | /// impl<T> Wrap<T> { | |
| 1517 | /// fn new(elem: T) -> Self { | |
| 1518 | /// Self { elem } | |
| 1519 | /// } | |
| 1520 | /// } | |
| 1521 | /// ``` | |
| 1522 | /// | |
| 1523 | /// In a [`trait`] definition and related [`impl`] block: | |
| 1524 | /// | |
| 1525 | /// ``` | |
| 1526 | /// trait Example { | |
| 1527 | /// fn example() -> Self; | |
| 1528 | /// } | |
| 1529 | /// | |
| 1530 | /// struct Foo(i32); | |
| 1531 | /// | |
| 1532 | /// impl Example for Foo { | |
| 1533 | /// fn example() -> Self { | |
| 1534 | /// Self(42) | |
| 1535 | /// } | |
| 1536 | /// } | |
| 1537 | /// | |
| 1538 | /// assert_eq!(Foo::example().0, Foo(42).0); | |
| 1539 | /// ``` | |
| 1540 | /// | |
| 1541 | /// [`impl`]: keyword.impl.html | |
| 1542 | /// [`trait`]: keyword.trait.html | |
| 1543 | mod self_upper_keyword {} | |
| 1544 | ||
| 1545 | #[doc(keyword = "static")] | |
| 1546 | // | |
| 1547 | /// A static item is a value which is valid for the entire duration of your | |
| 1548 | /// program (a `'static` lifetime). | |
| 1549 | /// | |
| 1550 | /// On the surface, `static` items seem very similar to [`const`]s: both contain | |
| 1551 | /// a value, both require type annotations and both can only be initialized with | |
| 1552 | /// constant functions and values. However, `static`s are notably different in | |
| 1553 | /// that they represent a location in memory. That means that you can have | |
| 1554 | /// references to `static` items and potentially even modify them, making them | |
| 1555 | /// essentially global variables. | |
| 1556 | /// | |
| 1557 | /// Static items do not call [`drop`] at the end of the program. | |
| 1558 | /// | |
| 1559 | /// There are two types of `static` items: those declared in association with | |
| 1560 | /// the [`mut`] keyword and those without. | |
| 1561 | /// | |
| 1562 | /// Static items cannot be moved: | |
| 1563 | /// | |
| 1564 | /// ```rust,compile_fail,E0507 | |
| 1565 | /// static VEC: Vec<u32> = vec![]; | |
| 1566 | /// | |
| 1567 | /// fn move_vec(v: Vec<u32>) -> Vec<u32> { | |
| 1568 | /// v | |
| 1569 | /// } | |
| 1570 | /// | |
| 1571 | /// // This line causes an error | |
| 1572 | /// move_vec(VEC); | |
| 1573 | /// ``` | |
| 1574 | /// | |
| 1575 | /// # Simple `static`s | |
| 1576 | /// | |
| 1577 | /// Accessing non-[`mut`] `static` items is considered safe, but some | |
| 1578 | /// restrictions apply. Most notably, the type of a `static` value needs to | |
| 1579 | /// implement the [`Sync`] trait, ruling out interior mutability containers | |
| 1580 | /// like [`RefCell`]. See the [Reference] for more information. | |
| 1581 | /// | |
| 1582 | /// ```rust | |
| 1583 | /// static FOO: [i32; 5] = [1, 2, 3, 4, 5]; | |
| 1584 | /// | |
| 1585 | /// let r1 = &FOO as *const _; | |
| 1586 | /// let r2 = &FOO as *const _; | |
| 1587 | /// // With a strictly read-only static, references will have the same address | |
| 1588 | /// assert_eq!(r1, r2); | |
| 1589 | /// // A static item can be used just like a variable in many cases | |
| 1590 | /// println!("{FOO:?}"); | |
| 1591 | /// ``` | |
| 1592 | /// | |
| 1593 | /// # Mutable `static`s | |
| 1594 | /// | |
| 1595 | /// If a `static` item is declared with the [`mut`] keyword, then it is allowed | |
| 1596 | /// to be modified by the program. However, accessing mutable `static`s can | |
| 1597 | /// cause undefined behavior in a number of ways, for example due to data races | |
| 1598 | /// in a multithreaded context. As such, all accesses to mutable `static`s | |
| 1599 | /// require an [`unsafe`] block. | |
| 1600 | /// | |
| 1601 | /// When possible, it's often better to use a non-mutable `static` with an | |
| 1602 | /// interior mutable type such as [`Mutex`], [`OnceLock`], or an [atomic]. | |
| 1603 | /// | |
| 1604 | /// Despite their unsafety, mutable `static`s are necessary in many contexts: | |
| 1605 | /// they can be used to represent global state shared by the whole program or in | |
| 1606 | /// [`extern`] blocks to bind to variables from C libraries. | |
| 1607 | /// | |
| 1608 | /// In an [`extern`] block: | |
| 1609 | /// | |
| 1610 | /// ```rust,no_run | |
| 1611 | /// # #![allow(dead_code)] | |
| 1612 | /// unsafe extern "C" { | |
| 1613 | /// static mut ERROR_MESSAGE: *mut std::os::raw::c_char; | |
| 1614 | /// } | |
| 1615 | /// ``` | |
| 1616 | /// | |
| 1617 | /// Mutable `static`s, just like simple `static`s, have some restrictions that | |
| 1618 | /// apply to them. See the [Reference] for more information. | |
| 1619 | /// | |
| 1620 | /// [`const`]: keyword.const.html | |
| 1621 | /// [`extern`]: keyword.extern.html | |
| 1622 | /// [`mut`]: keyword.mut.html | |
| 1623 | /// [`unsafe`]: keyword.unsafe.html | |
| 1624 | /// [`Mutex`]: ../std/sync/struct.Mutex.html | |
| 1625 | /// [`OnceLock`]: ../std/sync/struct.OnceLock.html | |
| 1626 | /// [`RefCell`]: cell::RefCell | |
| 1627 | /// [atomic]: sync::atomic | |
| 1628 | /// [Reference]: ../reference/items/static-items.html | |
| 1629 | mod static_keyword {} | |
| 1630 | ||
| 1631 | #[doc(keyword = "struct")] | |
| 1632 | // | |
| 1633 | /// A type that is composed of other types. | |
| 1634 | /// | |
| 1635 | /// Structs in Rust come in three flavors: Structs with named fields, tuple structs, and unit | |
| 1636 | /// structs. | |
| 1637 | /// | |
| 1638 | /// ```rust | |
| 1639 | /// struct Regular { | |
| 1640 | /// field1: f32, | |
| 1641 | /// field2: String, | |
| 1642 | /// pub field3: bool | |
| 1643 | /// } | |
| 1644 | /// | |
| 1645 | /// struct Tuple(u32, String); | |
| 1646 | /// | |
| 1647 | /// struct Unit; | |
| 1648 | /// ``` | |
| 1649 | /// | |
| 1650 | /// Regular structs are the most commonly used. Each field defined within them has a name and a | |
| 1651 | /// type, and once defined can be accessed using `example_struct.field` syntax. The fields of a | |
| 1652 | /// struct share its mutability, so `foo.bar = 2;` would only be valid if `foo` was mutable. Adding | |
| 1653 | /// `pub` to a field makes it visible to code in other modules, as well as allowing it to be | |
| 1654 | /// directly accessed and modified. | |
| 1655 | /// | |
| 1656 | /// Tuple structs are similar to regular structs, but its fields have no names. They are used like | |
| 1657 | /// tuples, with deconstruction possible via `let TupleStruct(x, y) = foo;` syntax. For accessing | |
| 1658 | /// individual variables, the same syntax is used as with regular tuples, namely `foo.0`, `foo.1`, | |
| 1659 | /// etc, starting at zero. | |
| 1660 | /// | |
| 1661 | /// Unit structs are most commonly used as marker. They have a size of zero bytes, but unlike empty | |
| 1662 | /// enums they can be instantiated, making them isomorphic to the unit type `()`. Unit structs are | |
| 1663 | /// useful when you need to implement a trait on something, but don't need to store any data inside | |
| 1664 | /// it. | |
| 1665 | /// | |
| 1666 | /// # Instantiation | |
| 1667 | /// | |
| 1668 | /// Structs can be instantiated in different ways, all of which can be mixed and | |
| 1669 | /// matched as needed. The most common way to make a new struct is via a constructor method such as | |
| 1670 | /// `new()`, but when that isn't available (or you're writing the constructor itself), struct | |
| 1671 | /// literal syntax is used: | |
| 1672 | /// | |
| 1673 | /// ```rust | |
| 1674 | /// # struct Foo { field1: f32, field2: String, etc: bool } | |
| 1675 | /// let example = Foo { | |
| 1676 | /// field1: 42.0, | |
| 1677 | /// field2: "blah".to_string(), | |
| 1678 | /// etc: true, | |
| 1679 | /// }; | |
| 1680 | /// ``` | |
| 1681 | /// | |
| 1682 | /// It's only possible to directly instantiate a struct using struct literal syntax when all of its | |
| 1683 | /// fields are visible to you. | |
| 1684 | /// | |
| 1685 | /// There are a handful of shortcuts provided to make writing constructors more convenient, most | |
| 1686 | /// common of which is the Field Init shorthand. When there is a variable and a field of the same | |
| 1687 | /// name, the assignment can be simplified from `field: field` into simply `field`. The following | |
| 1688 | /// example of a hypothetical constructor demonstrates this: | |
| 1689 | /// | |
| 1690 | /// ```rust | |
| 1691 | /// struct User { | |
| 1692 | /// name: String, | |
| 1693 | /// admin: bool, | |
| 1694 | /// } | |
| 1695 | /// | |
| 1696 | /// impl User { | |
| 1697 | /// pub fn new(name: String) -> Self { | |
| 1698 | /// Self { | |
| 1699 | /// name, | |
| 1700 | /// admin: false, | |
| 1701 | /// } | |
| 1702 | /// } | |
| 1703 | /// } | |
| 1704 | /// ``` | |
| 1705 | /// | |
| 1706 | /// Another shortcut for struct instantiation is available, used when you need to make a new | |
| 1707 | /// struct that has the same values as most of a previous struct of the same type, called struct | |
| 1708 | /// update syntax: | |
| 1709 | /// | |
| 1710 | /// ```rust | |
| 1711 | /// # struct Foo { field1: String, field2: () } | |
| 1712 | /// # let thing = Foo { field1: "".to_string(), field2: () }; | |
| 1713 | /// let updated_thing = Foo { | |
| 1714 | /// field1: "a new value".to_string(), | |
| 1715 | /// ..thing | |
| 1716 | /// }; | |
| 1717 | /// ``` | |
| 1718 | /// | |
| 1719 | /// Tuple structs are instantiated in the same way as tuples themselves, except with the struct's | |
| 1720 | /// name as a prefix: `Foo(123, false, 0.1)`. | |
| 1721 | /// | |
| 1722 | /// Empty structs are instantiated with just their name, and don't need anything else. `let thing = | |
| 1723 | /// EmptyStruct;` | |
| 1724 | /// | |
| 1725 | /// # Style conventions | |
| 1726 | /// | |
| 1727 | /// Structs are always written in UpperCamelCase, with few exceptions. While the trailing comma on a | |
| 1728 | /// struct's list of fields can be omitted, it's usually kept for convenience in adding and | |
| 1729 | /// removing fields down the line. | |
| 1730 | /// | |
| 1731 | /// For more information on structs, take a look at the [Rust Book][book] or the | |
| 1732 | /// [Reference][reference]. | |
| 1733 | /// | |
| 1734 | /// [`PhantomData`]: marker::PhantomData | |
| 1735 | /// [book]: ../book/ch05-01-defining-structs.html | |
| 1736 | /// [reference]: ../reference/items/structs.html | |
| 1737 | mod struct_keyword {} | |
| 1738 | ||
| 1739 | #[doc(keyword = "super")] | |
| 1740 | // | |
| 1741 | /// The parent of the current [module]. | |
| 1742 | /// | |
| 1743 | /// ```rust | |
| 1744 | /// # #![allow(dead_code)] | |
| 1745 | /// # fn main() {} | |
| 1746 | /// mod a { | |
| 1747 | /// pub fn foo() {} | |
| 1748 | /// } | |
| 1749 | /// mod b { | |
| 1750 | /// pub fn foo() { | |
| 1751 | /// super::a::foo(); // call a's foo function | |
| 1752 | /// } | |
| 1753 | /// } | |
| 1754 | /// ``` | |
| 1755 | /// | |
| 1756 | /// It is also possible to use `super` multiple times: `super::super::foo`, | |
| 1757 | /// going up the ancestor chain. | |
| 1758 | /// | |
| 1759 | /// See the [Reference] for more information. | |
| 1760 | /// | |
| 1761 | /// [module]: ../reference/items/modules.html | |
| 1762 | /// [Reference]: ../reference/paths.html#super | |
| 1763 | mod super_keyword {} | |
| 1764 | ||
| 1765 | #[doc(keyword = "trait")] | |
| 1766 | // | |
| 1767 | /// A common interface for a group of types. | |
| 1768 | /// | |
| 1769 | /// A `trait` is like an interface that data types can implement. When a type | |
| 1770 | /// implements a trait it can be treated abstractly as that trait using generics | |
| 1771 | /// or trait objects. | |
| 1772 | /// | |
| 1773 | /// Traits can be made up of three varieties of associated items: | |
| 1774 | /// | |
| 1775 | /// - functions and methods | |
| 1776 | /// - types | |
| 1777 | /// - constants | |
| 1778 | /// | |
| 1779 | /// Traits may also contain additional type parameters. Those type parameters | |
| 1780 | /// or the trait itself can be constrained by other traits. | |
| 1781 | /// | |
| 1782 | /// Traits can serve as markers or carry other logical semantics that | |
| 1783 | /// aren't expressed through their items. When a type implements that | |
| 1784 | /// trait it is promising to uphold its contract. [`Send`] and [`Sync`] are two | |
| 1785 | /// such marker traits present in the standard library. | |
| 1786 | /// | |
| 1787 | /// See the [Reference][Ref-Traits] for a lot more information on traits. | |
| 1788 | /// | |
| 1789 | /// # Examples | |
| 1790 | /// | |
| 1791 | /// Traits are declared using the `trait` keyword. Types can implement them | |
| 1792 | /// using [`impl`] `Trait` [`for`] `Type`: | |
| 1793 | /// | |
| 1794 | /// ```rust | |
| 1795 | /// trait Zero { | |
| 1796 | /// const ZERO: Self; | |
| 1797 | /// fn is_zero(&self) -> bool; | |
| 1798 | /// } | |
| 1799 | /// | |
| 1800 | /// impl Zero for i32 { | |
| 1801 | /// const ZERO: Self = 0; | |
| 1802 | /// | |
| 1803 | /// fn is_zero(&self) -> bool { | |
| 1804 | /// *self == Self::ZERO | |
| 1805 | /// } | |
| 1806 | /// } | |
| 1807 | /// | |
| 1808 | /// assert_eq!(i32::ZERO, 0); | |
| 1809 | /// assert!(i32::ZERO.is_zero()); | |
| 1810 | /// assert!(!4.is_zero()); | |
| 1811 | /// ``` | |
| 1812 | /// | |
| 1813 | /// With an associated type: | |
| 1814 | /// | |
| 1815 | /// ```rust | |
| 1816 | /// trait Builder { | |
| 1817 | /// type Built; | |
| 1818 | /// | |
| 1819 | /// fn build(&self) -> Self::Built; | |
| 1820 | /// } | |
| 1821 | /// ``` | |
| 1822 | /// | |
| 1823 | /// Traits can be generic, with constraints or without: | |
| 1824 | /// | |
| 1825 | /// ```rust | |
| 1826 | /// trait MaybeFrom<T> { | |
| 1827 | /// fn maybe_from(value: T) -> Option<Self> | |
| 1828 | /// where | |
| 1829 | /// Self: Sized; | |
| 1830 | /// } | |
| 1831 | /// ``` | |
| 1832 | /// | |
| 1833 | /// Traits can build upon the requirements of other traits. In the example | |
| 1834 | /// below `Iterator` is a **supertrait** and `ThreeIterator` is a **subtrait**: | |
| 1835 | /// | |
| 1836 | /// ```rust | |
| 1837 | /// trait ThreeIterator: Iterator { | |
| 1838 | /// fn next_three(&mut self) -> Option<[Self::Item; 3]>; | |
| 1839 | /// } | |
| 1840 | /// ``` | |
| 1841 | /// | |
| 1842 | /// Traits can be used in functions, as parameters: | |
| 1843 | /// | |
| 1844 | /// ```rust | |
| 1845 | /// # #![allow(dead_code)] | |
| 1846 | /// fn debug_iter<I: Iterator>(it: I) where I::Item: std::fmt::Debug { | |
| 1847 | /// for elem in it { | |
| 1848 | /// println!("{elem:#?}"); | |
| 1849 | /// } | |
| 1850 | /// } | |
| 1851 | /// | |
| 1852 | /// // u8_len_1, u8_len_2 and u8_len_3 are equivalent | |
| 1853 | /// | |
| 1854 | /// fn u8_len_1(val: impl Into<Vec<u8>>) -> usize { | |
| 1855 | /// val.into().len() | |
| 1856 | /// } | |
| 1857 | /// | |
| 1858 | /// fn u8_len_2<T: Into<Vec<u8>>>(val: T) -> usize { | |
| 1859 | /// val.into().len() | |
| 1860 | /// } | |
| 1861 | /// | |
| 1862 | /// fn u8_len_3<T>(val: T) -> usize | |
| 1863 | /// where | |
| 1864 | /// T: Into<Vec<u8>>, | |
| 1865 | /// { | |
| 1866 | /// val.into().len() | |
| 1867 | /// } | |
| 1868 | /// ``` | |
| 1869 | /// | |
| 1870 | /// Or as return types: | |
| 1871 | /// | |
| 1872 | /// ```rust | |
| 1873 | /// # #![allow(dead_code)] | |
| 1874 | /// fn from_zero_to(v: u8) -> impl Iterator<Item = u8> { | |
| 1875 | /// (0..v).into_iter() | |
| 1876 | /// } | |
| 1877 | /// ``` | |
| 1878 | /// | |
| 1879 | /// The use of the [`impl`] keyword in this position allows the function writer | |
| 1880 | /// to hide the concrete type as an implementation detail which can change | |
| 1881 | /// without breaking user's code. | |
| 1882 | /// | |
| 1883 | /// # Trait objects | |
| 1884 | /// | |
| 1885 | /// A *trait object* is an opaque value of another type that implements a set of | |
| 1886 | /// traits. A trait object implements all specified traits as well as their | |
| 1887 | /// supertraits (if any). | |
| 1888 | /// | |
| 1889 | /// The syntax is the following: `dyn BaseTrait + AutoTrait1 + ... AutoTraitN`. | |
| 1890 | /// Only one `BaseTrait` can be used so this will not compile: | |
| 1891 | /// | |
| 1892 | /// ```rust,compile_fail,E0225 | |
| 1893 | /// trait A {} | |
| 1894 | /// trait B {} | |
| 1895 | /// | |
| 1896 | /// let _: Box<dyn A + B>; | |
| 1897 | /// ``` | |
| 1898 | /// | |
| 1899 | /// Neither will this, which is a syntax error: | |
| 1900 | /// | |
| 1901 | /// ```rust,compile_fail | |
| 1902 | /// trait A {} | |
| 1903 | /// trait B {} | |
| 1904 | /// | |
| 1905 | /// let _: Box<dyn A + dyn B>; | |
| 1906 | /// ``` | |
| 1907 | /// | |
| 1908 | /// On the other hand, this is correct: | |
| 1909 | /// | |
| 1910 | /// ```rust | |
| 1911 | /// trait A {} | |
| 1912 | /// | |
| 1913 | /// let _: Box<dyn A + Send + Sync>; | |
| 1914 | /// ``` | |
| 1915 | /// | |
| 1916 | /// The [Reference][Ref-Trait-Objects] has more information about trait objects, | |
| 1917 | /// their limitations and the differences between editions. | |
| 1918 | /// | |
| 1919 | /// # Unsafe traits | |
| 1920 | /// | |
| 1921 | /// Some traits may be unsafe to implement. Using the [`unsafe`] keyword in | |
| 1922 | /// front of the trait's declaration is used to mark this: | |
| 1923 | /// | |
| 1924 | /// ```rust | |
| 1925 | /// unsafe trait UnsafeTrait {} | |
| 1926 | /// | |
| 1927 | /// unsafe impl UnsafeTrait for i32 {} | |
| 1928 | /// ``` | |
| 1929 | /// | |
| 1930 | /// # Differences between the 2015 and 2018 editions | |
| 1931 | /// | |
| 1932 | /// In the 2015 edition the parameters pattern was not needed for traits: | |
| 1933 | /// | |
| 1934 | /// ```rust,edition2015 | |
| 1935 | /// # #![allow(anonymous_parameters)] | |
| 1936 | /// trait Tr { | |
| 1937 | /// fn f(i32); | |
| 1938 | /// } | |
| 1939 | /// ``` | |
| 1940 | /// | |
| 1941 | /// This behavior is no longer valid in edition 2018. | |
| 1942 | /// | |
| 1943 | /// [`for`]: keyword.for.html | |
| 1944 | /// [`impl`]: keyword.impl.html | |
| 1945 | /// [`unsafe`]: keyword.unsafe.html | |
| 1946 | /// [Ref-Traits]: ../reference/items/traits.html | |
| 1947 | /// [Ref-Trait-Objects]: ../reference/types/trait-object.html | |
| 1948 | mod trait_keyword {} | |
| 1949 | ||
| 1950 | #[doc(keyword = "true")] | |
| 1951 | // | |
| 1952 | /// A value of type [`prim@bool`] representing logical **true**. | |
| 1953 | /// | |
| 1954 | /// Logically `true` is not equal to [`false`]. | |
| 1955 | /// | |
| 1956 | /// ## Control structures that check for **true** | |
| 1957 | /// | |
| 1958 | /// Several of Rust's control structures will check for a `bool` condition evaluating to **true**. | |
| 1959 | /// | |
| 1960 | /// * The condition in an [`if`] expression must be of type `bool`. | |
| 1961 | /// Whenever that condition evaluates to **true**, the `if` expression takes | |
| 1962 | /// on the value of the first block. If however, the condition evaluates | |
| 1963 | /// to `false`, the expression takes on value of the `else` block if there is one. | |
| 1964 | /// | |
| 1965 | /// * [`while`] is another control flow construct expecting a `bool`-typed condition. | |
| 1966 | /// As long as the condition evaluates to **true**, the `while` loop will continually | |
| 1967 | /// evaluate its associated block. | |
| 1968 | /// | |
| 1969 | /// * [`match`] arms can have guard clauses on them. | |
| 1970 | /// | |
| 1971 | /// [`if`]: keyword.if.html | |
| 1972 | /// [`while`]: keyword.while.html | |
| 1973 | /// [`match`]: ../reference/expressions/match-expr.html#match-guards | |
| 1974 | /// [`false`]: keyword.false.html | |
| 1975 | mod true_keyword {} | |
| 1976 | ||
| 1977 | #[doc(keyword = "type")] | |
| 1978 | // | |
| 1979 | /// Define an [alias] for an existing type. | |
| 1980 | /// | |
| 1981 | /// The syntax is `type Name = ExistingType;`. | |
| 1982 | /// | |
| 1983 | /// # Examples | |
| 1984 | /// | |
| 1985 | /// `type` does **not** create a new type: | |
| 1986 | /// | |
| 1987 | /// ```rust | |
| 1988 | /// type Meters = u32; | |
| 1989 | /// type Kilograms = u32; | |
| 1990 | /// | |
| 1991 | /// let m: Meters = 3; | |
| 1992 | /// let k: Kilograms = 3; | |
| 1993 | /// | |
| 1994 | /// assert_eq!(m, k); | |
| 1995 | /// ``` | |
| 1996 | /// | |
| 1997 | /// A type can be generic: | |
| 1998 | /// | |
| 1999 | /// ```rust | |
| 2000 | /// # use std::sync::{Arc, Mutex}; | |
| 2001 | /// type ArcMutex<T> = Arc<Mutex<T>>; | |
| 2002 | /// ``` | |
| 2003 | /// | |
| 2004 | /// In traits, `type` is used to declare an [associated type]: | |
| 2005 | /// | |
| 2006 | /// ```rust | |
| 2007 | /// trait Iterator { | |
| 2008 | /// // associated type declaration | |
| 2009 | /// type Item; | |
| 2010 | /// fn next(&mut self) -> Option<Self::Item>; | |
| 2011 | /// } | |
| 2012 | /// | |
| 2013 | /// struct Once<T>(Option<T>); | |
| 2014 | /// | |
| 2015 | /// impl<T> Iterator for Once<T> { | |
| 2016 | /// // associated type definition | |
| 2017 | /// type Item = T; | |
| 2018 | /// fn next(&mut self) -> Option<Self::Item> { | |
| 2019 | /// self.0.take() | |
| 2020 | /// } | |
| 2021 | /// } | |
| 2022 | /// ``` | |
| 2023 | /// | |
| 2024 | /// [`trait`]: keyword.trait.html | |
| 2025 | /// [associated type]: ../reference/items/associated-items.html#associated-types | |
| 2026 | /// [alias]: ../reference/items/type-aliases.html | |
| 2027 | mod type_keyword {} | |
| 2028 | ||
| 2029 | #[doc(keyword = "unsafe")] | |
| 2030 | // | |
| 2031 | /// Code or interfaces whose [memory safety] cannot be verified by the type | |
| 2032 | /// system. | |
| 2033 | /// | |
| 2034 | /// The `unsafe` keyword has two uses: | |
| 2035 | /// - to declare the existence of contracts the compiler can't check, | |
| 2036 | /// - and to declare that a programmer has checked that these contracts have been upheld. | |
| 2037 | /// | |
| 2038 | /// Typically, each `unsafe` is either of the first or second kind: `unsafe fn` and `unsafe trait` | |
| 2039 | /// declare the existence of an unsafe contract; `unsafe {}` and `unsafe impl` declare that an | |
| 2040 | /// unsafe contract (which must have been declared elsewhere) is being upheld. | |
| 2041 | /// | |
| 2042 | /// However, historically, these two are not mutually exclusive: the body of an `unsafe fn` is, on | |
| 2043 | /// old editions, treated like an unsafe block, which means that this use of `unsafe` both declares | |
| 2044 | /// the existence of a contract to call the current function, and declares that the contracts of the | |
| 2045 | /// unsafe operations inside this function are being upheld. The `unsafe_op_in_unsafe_fn` lint can | |
| 2046 | /// be enabled to change that and make `unsafe fn` only play the former role. That lint is enabled | |
| 2047 | /// by default since edition 2024. | |
| 2048 | /// | |
| 2049 | /// # Unsafe abilities | |
| 2050 | /// | |
| 2051 | /// **No matter what, Safe Rust can't cause Undefined Behavior**. This is | |
| 2052 | /// referred to as [soundness]: a well-typed program actually has the desired | |
| 2053 | /// properties. The [Nomicon][nomicon-soundness] has a more detailed explanation | |
| 2054 | /// on the subject. | |
| 2055 | /// | |
| 2056 | /// To ensure soundness, Safe Rust is restricted enough that it can be | |
| 2057 | /// automatically checked. Sometimes, however, it is necessary to write code | |
| 2058 | /// that is correct for reasons which are too clever for the compiler to | |
| 2059 | /// understand. In those cases, you need to use Unsafe Rust. | |
| 2060 | /// | |
| 2061 | /// Here are the abilities Unsafe Rust has in addition to Safe Rust: | |
| 2062 | /// | |
| 2063 | /// - Dereference [raw pointers] | |
| 2064 | /// - Implement `unsafe` [`trait`]s | |
| 2065 | /// - Call `unsafe` functions | |
| 2066 | /// - Mutate [`static`]s (including [`extern`]al ones) | |
| 2067 | /// - Access fields of [`union`]s | |
| 2068 | /// | |
| 2069 | /// However, this extra power comes with extra responsibilities: it is now up to | |
| 2070 | /// you to ensure soundness. The `unsafe` keyword helps by clearly marking the | |
| 2071 | /// pieces of code that need to worry about this. | |
| 2072 | /// | |
| 2073 | /// ## The different meanings of `unsafe` | |
| 2074 | /// | |
| 2075 | /// Not all uses of `unsafe` are equivalent: some are here to mark the existence | |
| 2076 | /// of a contract the programmer must check, others are to say "I have checked | |
| 2077 | /// the contract, go ahead and do this". The following | |
| 2078 | /// [discussion on Rust Internals] has more in-depth explanations about this but | |
| 2079 | /// here is a summary of the main points: | |
| 2080 | /// | |
| 2081 | /// - `unsafe fn`: calling this function means abiding by a contract the | |
| 2082 | /// compiler cannot enforce. | |
| 2083 | /// - `unsafe trait`: implementing the [`trait`] means abiding by a | |
| 2084 | /// contract the compiler cannot enforce. | |
| 2085 | /// - `unsafe {}`: the contract necessary to call the operations inside the | |
| 2086 | /// block has been checked by the programmer and is guaranteed to be respected. | |
| 2087 | /// - `unsafe impl`: the contract necessary to implement the trait has been | |
| 2088 | /// checked by the programmer and is guaranteed to be respected. | |
| 2089 | /// | |
| 2090 | /// On old editions, `unsafe fn` also acts like an `unsafe {}` block around the code inside the | |
| 2091 | /// function. This means it is not just a signal to the caller, but also promises that the | |
| 2092 | /// preconditions for the operations inside the function are upheld. Mixing these two meanings can | |
| 2093 | /// be confusing, so the `unsafe_op_in_unsafe_fn` lint has been introduced and enabled by default | |
| 2094 | /// since edition 2024 to warn against that and require explicit unsafe blocks even inside `unsafe | |
| 2095 | /// fn`. | |
| 2096 | /// | |
| 2097 | /// See the [Rustonomicon] and the [Reference] for more information. | |
| 2098 | /// | |
| 2099 | /// # Examples | |
| 2100 | /// | |
| 2101 | /// ## Marking elements as `unsafe` | |
| 2102 | /// | |
| 2103 | /// `unsafe` can be used on functions. Note that functions and statics declared | |
| 2104 | /// in [`extern`] blocks are implicitly marked as `unsafe` (but not functions | |
| 2105 | /// declared as `extern "something" fn ...`). Mutable statics are always unsafe, | |
| 2106 | /// wherever they are declared. Methods can also be declared as `unsafe`: | |
| 2107 | /// | |
| 2108 | /// ```rust | |
| 2109 | /// # #![allow(dead_code)] | |
| 2110 | /// static mut FOO: &str = "hello"; | |
| 2111 | /// | |
| 2112 | /// unsafe fn unsafe_fn() {} | |
| 2113 | /// | |
| 2114 | /// unsafe extern "C" { | |
| 2115 | /// fn unsafe_extern_fn(); | |
| 2116 | /// static BAR: *mut u32; | |
| 2117 | /// } | |
| 2118 | /// | |
| 2119 | /// trait SafeTraitWithUnsafeMethod { | |
| 2120 | /// unsafe fn unsafe_method(&self); | |
| 2121 | /// } | |
| 2122 | /// | |
| 2123 | /// struct S; | |
| 2124 | /// | |
| 2125 | /// impl S { | |
| 2126 | /// unsafe fn unsafe_method_on_struct() {} | |
| 2127 | /// } | |
| 2128 | /// ``` | |
| 2129 | /// | |
| 2130 | /// Traits can also be declared as `unsafe`: | |
| 2131 | /// | |
| 2132 | /// ```rust | |
| 2133 | /// unsafe trait UnsafeTrait {} | |
| 2134 | /// ``` | |
| 2135 | /// | |
| 2136 | /// Since `unsafe fn` and `unsafe trait` indicate that there is a safety | |
| 2137 | /// contract that the compiler cannot enforce, documenting it is important. The | |
| 2138 | /// standard library has many examples of this, like the following which is an | |
| 2139 | /// extract from [`Vec::set_len`]. The `# Safety` section explains the contract | |
| 2140 | /// that must be fulfilled to safely call the function. | |
| 2141 | /// | |
| 2142 | /// ```rust,ignore (stub-to-show-doc-example) | |
| 2143 | /// /// Forces the length of the vector to `new_len`. | |
| 2144 | /// /// | |
| 2145 | /// /// This is a low-level operation that maintains none of the normal | |
| 2146 | /// /// invariants of the type. Normally changing the length of a vector | |
| 2147 | /// /// is done using one of the safe operations instead, such as | |
| 2148 | /// /// `truncate`, `resize`, `extend`, or `clear`. | |
| 2149 | /// /// | |
| 2150 | /// /// # Safety | |
| 2151 | /// /// | |
| 2152 | /// /// - `new_len` must be less than or equal to `capacity()`. | |
| 2153 | /// /// - The elements at `old_len..new_len` must be initialized. | |
| 2154 | /// pub unsafe fn set_len(&mut self, new_len: usize) | |
| 2155 | /// ``` | |
| 2156 | /// | |
| 2157 | /// ## Using `unsafe {}` blocks and `impl`s | |
| 2158 | /// | |
| 2159 | /// Performing `unsafe` operations requires an `unsafe {}` block: | |
| 2160 | /// | |
| 2161 | /// ```rust | |
| 2162 | /// # #![allow(dead_code)] | |
| 2163 | /// #![deny(unsafe_op_in_unsafe_fn)] | |
| 2164 | /// | |
| 2165 | /// /// Dereference the given pointer. | |
| 2166 | /// /// | |
| 2167 | /// /// # Safety | |
| 2168 | /// /// | |
| 2169 | /// /// `ptr` must be aligned and must not be dangling. | |
| 2170 | /// unsafe fn deref_unchecked(ptr: *const i32) -> i32 { | |
| 2171 | /// // SAFETY: the caller is required to ensure that `ptr` is aligned and dereferenceable. | |
| 2172 | /// unsafe { *ptr } | |
| 2173 | /// } | |
| 2174 | /// | |
| 2175 | /// let a = 3; | |
| 2176 | /// let b = &a as *const _; | |
| 2177 | /// // SAFETY: `a` has not been dropped and references are always aligned, | |
| 2178 | /// // so `b` is a valid address. | |
| 2179 | /// unsafe { assert_eq!(*b, deref_unchecked(b)); }; | |
| 2180 | /// ``` | |
| 2181 | /// | |
| 2182 | /// ## `unsafe` and traits | |
| 2183 | /// | |
| 2184 | /// The interactions of `unsafe` and traits can be surprising, so let us contrast the | |
| 2185 | /// two combinations of safe `fn` in `unsafe trait` and `unsafe fn` in safe trait using two | |
| 2186 | /// examples: | |
| 2187 | /// | |
| 2188 | /// ```rust | |
| 2189 | /// /// # Safety | |
| 2190 | /// /// | |
| 2191 | /// /// `make_even` must return an even number. | |
| 2192 | /// unsafe trait MakeEven { | |
| 2193 | /// fn make_even(&self) -> i32; | |
| 2194 | /// } | |
| 2195 | /// | |
| 2196 | /// // SAFETY: Our `make_even` always returns something even. | |
| 2197 | /// unsafe impl MakeEven for i32 { | |
| 2198 | /// fn make_even(&self) -> i32 { | |
| 2199 | /// self << 1 | |
| 2200 | /// } | |
| 2201 | /// } | |
| 2202 | /// | |
| 2203 | /// fn use_make_even(x: impl MakeEven) { | |
| 2204 | /// if x.make_even() % 2 == 1 { | |
| 2205 | /// // SAFETY: this can never happen, because all `MakeEven` implementations | |
| 2206 | /// // ensure that `make_even` returns something even. | |
| 2207 | /// unsafe { std::hint::unreachable_unchecked() }; | |
| 2208 | /// } | |
| 2209 | /// } | |
| 2210 | /// ``` | |
| 2211 | /// | |
| 2212 | /// Note how the safety contract of the trait is upheld by the implementation, and is itself used to | |
| 2213 | /// uphold the safety contract of the unsafe function `unreachable_unchecked` called by | |
| 2214 | /// `use_make_even`. `make_even` itself is a safe function because its *callers* do not have to | |
| 2215 | /// worry about any contract, only the *implementation* of `MakeEven` is required to uphold a | |
| 2216 | /// certain contract. `use_make_even` is safe because it can use the promise made by `MakeEven` | |
| 2217 | /// implementations to uphold the safety contract of the `unsafe fn unreachable_unchecked` it calls. | |
| 2218 | /// | |
| 2219 | /// It is also possible to have `unsafe fn` in a regular safe `trait`: | |
| 2220 | /// | |
| 2221 | /// ```rust | |
| 2222 | /// # #![feature(never_type)] | |
| 2223 | /// #![deny(unsafe_op_in_unsafe_fn)] | |
| 2224 | /// | |
| 2225 | /// trait Indexable { | |
| 2226 | /// const LEN: usize; | |
| 2227 | /// | |
| 2228 | /// /// # Safety | |
| 2229 | /// /// | |
| 2230 | /// /// The caller must ensure that `idx < LEN`. | |
| 2231 | /// unsafe fn idx_unchecked(&self, idx: usize) -> i32; | |
| 2232 | /// } | |
| 2233 | /// | |
| 2234 | /// // The implementation for `i32` doesn't need to do any contract reasoning. | |
| 2235 | /// impl Indexable for i32 { | |
| 2236 | /// const LEN: usize = 1; | |
| 2237 | /// | |
| 2238 | /// /// See `Indexable` for the safety contract. | |
| 2239 | /// unsafe fn idx_unchecked(&self, idx: usize) -> i32 { | |
| 2240 | /// debug_assert_eq!(idx, 0); | |
| 2241 | /// *self | |
| 2242 | /// } | |
| 2243 | /// } | |
| 2244 | /// | |
| 2245 | /// // The implementation for arrays exploits the function contract to | |
| 2246 | /// // make use of `get_unchecked` on slices and avoid a run-time check. | |
| 2247 | /// impl Indexable for [i32; 42] { | |
| 2248 | /// const LEN: usize = 42; | |
| 2249 | /// | |
| 2250 | /// /// See `Indexable` for the safety contract. | |
| 2251 | /// unsafe fn idx_unchecked(&self, idx: usize) -> i32 { | |
| 2252 | /// // SAFETY: As per this trait's documentation, the caller ensures | |
| 2253 | /// // that `idx < 42`. | |
| 2254 | /// unsafe { *self.get_unchecked(idx) } | |
| 2255 | /// } | |
| 2256 | /// } | |
| 2257 | /// | |
| 2258 | /// // The implementation for the never type declares a length of 0, | |
| 2259 | /// // which means `idx_unchecked` can never be called. | |
| 2260 | /// impl Indexable for ! { | |
| 2261 | /// const LEN: usize = 0; | |
| 2262 | /// | |
| 2263 | /// /// See `Indexable` for the safety contract. | |
| 2264 | /// unsafe fn idx_unchecked(&self, idx: usize) -> i32 { | |
| 2265 | /// // SAFETY: As per this trait's documentation, the caller ensures | |
| 2266 | /// // that `idx < 0`, which is impossible, so this is dead code. | |
| 2267 | /// unsafe { std::hint::unreachable_unchecked() } | |
| 2268 | /// } | |
| 2269 | /// } | |
| 2270 | /// | |
| 2271 | /// fn use_indexable<I: Indexable>(x: I, idx: usize) -> i32 { | |
| 2272 | /// if idx < I::LEN { | |
| 2273 | /// // SAFETY: We have checked that `idx < I::LEN`. | |
| 2274 | /// unsafe { x.idx_unchecked(idx) } | |
| 2275 | /// } else { | |
| 2276 | /// panic!("index out-of-bounds") | |
| 2277 | /// } | |
| 2278 | /// } | |
| 2279 | /// ``` | |
| 2280 | /// | |
| 2281 | /// This time, `use_indexable` is safe because it uses a run-time check to discharge the safety | |
| 2282 | /// contract of `idx_unchecked`. Implementing `Indexable` is safe because when writing | |
| 2283 | /// `idx_unchecked`, we don't have to worry: our *callers* need to discharge a proof obligation | |
| 2284 | /// (like `use_indexable` does), but the *implementation* of `get_unchecked` has no proof obligation | |
| 2285 | /// to contend with. Of course, the implementation may choose to call other unsafe operations, and | |
| 2286 | /// then it needs an `unsafe` *block* to indicate it discharged the proof obligations of its | |
| 2287 | /// callees. For that purpose it can make use of the contract that all its callers must uphold -- | |
| 2288 | /// the fact that `idx < LEN`. | |
| 2289 | /// | |
| 2290 | /// Note that unlike normal `unsafe fn`, an `unsafe fn` in a trait implementation does not get to | |
| 2291 | /// just pick an arbitrary safety contract! It *has* to use the safety contract defined by the trait | |
| 2292 | /// (or one with weaker preconditions). | |
| 2293 | /// | |
| 2294 | /// Formally speaking, an `unsafe fn` in a trait is a function with *preconditions* that go beyond | |
| 2295 | /// those encoded by the argument types (such as `idx < LEN`), whereas an `unsafe trait` can declare | |
| 2296 | /// that some of its functions have *postconditions* that go beyond those encoded in the return type | |
| 2297 | /// (such as returning an even integer). If a trait needs a function with both extra precondition | |
| 2298 | /// and extra postcondition, then it needs an `unsafe fn` in an `unsafe trait`. | |
| 2299 | /// | |
| 2300 | /// [`extern`]: keyword.extern.html | |
| 2301 | /// [`trait`]: keyword.trait.html | |
| 2302 | /// [`static`]: keyword.static.html | |
| 2303 | /// [`union`]: keyword.union.html | |
| 2304 | /// [`impl`]: keyword.impl.html | |
| 2305 | /// [`Vec::set_len`]: ../std/vec/struct.Vec.html#method.set_len | |
| 2306 | /// [raw pointers]: ../reference/types/pointer.html | |
| 2307 | /// [memory safety]: ../book/ch19-01-unsafe-rust.html | |
| 2308 | /// [Rustonomicon]: ../nomicon/index.html | |
| 2309 | /// [nomicon-soundness]: ../nomicon/safe-unsafe-meaning.html | |
| 2310 | /// [soundness]: https://rust-lang.github.io/unsafe-code-guidelines/glossary.html#soundness-of-code--of-a-library | |
| 2311 | /// [Reference]: ../reference/unsafety.html | |
| 2312 | /// [discussion on Rust Internals]: https://internals.rust-lang.org/t/what-does-unsafe-mean/6696 | |
| 2313 | mod unsafe_keyword {} | |
| 2314 | ||
| 2315 | #[doc(keyword = "use")] | |
| 2316 | // | |
| 2317 | /// Import or rename items from other crates or modules, use values under ergonomic clones | |
| 2318 | /// semantic, or specify precise capturing with `use<..>`. | |
| 2319 | /// | |
| 2320 | /// ## Importing items | |
| 2321 | /// | |
| 2322 | /// The `use` keyword is employed to shorten the path required to refer to a module item. | |
| 2323 | /// The keyword may appear in modules, blocks, and even functions, typically at the top. | |
| 2324 | /// | |
| 2325 | /// The most basic usage of the keyword is `use path::to::item;`, | |
| 2326 | /// though a number of convenient shortcuts are supported: | |
| 2327 | /// | |
| 2328 | /// * Simultaneously binding a list of paths with a common prefix, | |
| 2329 | /// using the glob-like brace syntax `use a::b::{c, d, e::f, g::h::i};` | |
| 2330 | /// * Simultaneously binding a list of paths with a common prefix and their common parent module, | |
| 2331 | /// using the [`self`] keyword, such as `use a::b::{self, c, d::e};` | |
| 2332 | /// * Rebinding the target name as a new local name, using the syntax `use p::q::r as x;`. | |
| 2333 | /// This can also be used with the last two features: `use a::b::{self as ab, c as abc}`. | |
| 2334 | /// * Binding all paths matching a given prefix, | |
| 2335 | /// using the asterisk wildcard syntax `use a::b::*;`. | |
| 2336 | /// * Nesting groups of the previous features multiple times, | |
| 2337 | /// such as `use a::b::{self as ab, c, d::{*, e::f}};` | |
| 2338 | /// * Reexporting with visibility modifiers such as `pub use a::b;` | |
| 2339 | /// * Importing with `_` to only import the methods of a trait without binding it to a name | |
| 2340 | /// (to avoid conflict for example): `use ::std::io::Read as _;`. | |
| 2341 | /// | |
| 2342 | /// Using path qualifiers like [`crate`], [`super`] or [`self`] is supported: `use crate::a::b;`. | |
| 2343 | /// | |
| 2344 | /// Note that when the wildcard `*` is used on a type, it does not import its methods (though | |
| 2345 | /// for `enum`s it imports the variants, as shown in the example below). | |
| 2346 | /// | |
| 2347 | /// ```compile_fail,edition2018 | |
| 2348 | /// enum ExampleEnum { | |
| 2349 | /// VariantA, | |
| 2350 | /// VariantB, | |
| 2351 | /// } | |
| 2352 | /// | |
| 2353 | /// impl ExampleEnum { | |
| 2354 | /// fn new() -> Self { | |
| 2355 | /// Self::VariantA | |
| 2356 | /// } | |
| 2357 | /// } | |
| 2358 | /// | |
| 2359 | /// use ExampleEnum::*; | |
| 2360 | /// | |
| 2361 | /// // Compiles. | |
| 2362 | /// let _ = VariantA; | |
| 2363 | /// | |
| 2364 | /// // Does not compile! | |
| 2365 | /// let n = new(); | |
| 2366 | /// ``` | |
| 2367 | /// | |
| 2368 | /// For more information on `use` and paths in general, see the [Reference][ref-use-decls]. | |
| 2369 | /// | |
| 2370 | /// The differences about paths and the `use` keyword between the 2015 and 2018 editions | |
| 2371 | /// can also be found in the [Reference][ref-use-decls]. | |
| 2372 | /// | |
| 2373 | /// ## Precise capturing | |
| 2374 | /// | |
| 2375 | /// The `use<..>` syntax is used within certain `impl Trait` bounds to control which generic | |
| 2376 | /// parameters are captured. This is important for return-position `impl Trait` (RPIT) types, | |
| 2377 | /// as it affects borrow checking by controlling which generic parameters can be used in the | |
| 2378 | /// hidden type. | |
| 2379 | /// | |
| 2380 | /// For example, the following function demonstrates an error without precise capturing in | |
| 2381 | /// Rust 2021 and earlier editions: | |
| 2382 | /// | |
| 2383 | /// ```rust,compile_fail,edition2021 | |
| 2384 | /// fn f(x: &()) -> impl Sized { x } | |
| 2385 | /// ``` | |
| 2386 | /// | |
| 2387 | /// By using `use<'_>` for precise capturing, it can be resolved: | |
| 2388 | /// | |
| 2389 | /// ```rust | |
| 2390 | /// fn f(x: &()) -> impl Sized + use<'_> { x } | |
| 2391 | /// ``` | |
| 2392 | /// | |
| 2393 | /// This syntax specifies that the elided lifetime be captured and therefore available for | |
| 2394 | /// use in the hidden type. | |
| 2395 | /// | |
| 2396 | /// In Rust 2024, opaque types automatically capture all lifetime parameters in scope. | |
| 2397 | /// `use<..>` syntax serves as an important way of opting-out of that default. | |
| 2398 | /// | |
| 2399 | /// For more details about precise capturing, see the [Reference][ref-impl-trait]. | |
| 2400 | /// | |
| 2401 | /// ## Ergonomic clones | |
| 2402 | /// | |
| 2403 | /// Use a values, copying its content if the value implements `Copy`, cloning the contents if the | |
| 2404 | /// value implements `UseCloned` or moving it otherwise. | |
| 2405 | /// | |
| 2406 | /// [`crate`]: keyword.crate.html | |
| 2407 | /// [`self`]: keyword.self.html | |
| 2408 | /// [`super`]: keyword.super.html | |
| 2409 | /// [ref-use-decls]: ../reference/items/use-declarations.html | |
| 2410 | /// [ref-impl-trait]: ../reference/types/impl-trait.html | |
| 2411 | mod use_keyword {} | |
| 2412 | ||
| 2413 | #[doc(keyword = "where")] | |
| 2414 | // | |
| 2415 | /// Add constraints that must be upheld to use an item. | |
| 2416 | /// | |
| 2417 | /// `where` allows specifying constraints on lifetime and generic parameters. | |
| 2418 | /// The [RFC] introducing `where` contains detailed information about the | |
| 2419 | /// keyword. | |
| 2420 | /// | |
| 2421 | /// # Examples | |
| 2422 | /// | |
| 2423 | /// `where` can be used for constraints with traits: | |
| 2424 | /// | |
| 2425 | /// ```rust | |
| 2426 | /// fn new<T: Default>() -> T { | |
| 2427 | /// T::default() | |
| 2428 | /// } | |
| 2429 | /// | |
| 2430 | /// fn new_where<T>() -> T | |
| 2431 | /// where | |
| 2432 | /// T: Default, | |
| 2433 | /// { | |
| 2434 | /// T::default() | |
| 2435 | /// } | |
| 2436 | /// | |
| 2437 | /// assert_eq!(0.0, new()); | |
| 2438 | /// assert_eq!(0.0, new_where()); | |
| 2439 | /// | |
| 2440 | /// assert_eq!(0, new()); | |
| 2441 | /// assert_eq!(0, new_where()); | |
| 2442 | /// ``` | |
| 2443 | /// | |
| 2444 | /// `where` can also be used for lifetimes. | |
| 2445 | /// | |
| 2446 | /// This compiles because `longer` outlives `shorter`, thus the constraint is | |
| 2447 | /// respected: | |
| 2448 | /// | |
| 2449 | /// ```rust | |
| 2450 | /// fn select<'short, 'long>(s1: &'short str, s2: &'long str, second: bool) -> &'short str | |
| 2451 | /// where | |
| 2452 | /// 'long: 'short, | |
| 2453 | /// { | |
| 2454 | /// if second { s2 } else { s1 } | |
| 2455 | /// } | |
| 2456 | /// | |
| 2457 | /// let outer = String::from("Long living ref"); | |
| 2458 | /// let longer = &outer; | |
| 2459 | /// { | |
| 2460 | /// let inner = String::from("Short living ref"); | |
| 2461 | /// let shorter = &inner; | |
| 2462 | /// | |
| 2463 | /// assert_eq!(select(shorter, longer, false), shorter); | |
| 2464 | /// assert_eq!(select(shorter, longer, true), longer); | |
| 2465 | /// } | |
| 2466 | /// ``` | |
| 2467 | /// | |
| 2468 | /// On the other hand, this will not compile because the `where 'b: 'a` clause | |
| 2469 | /// is missing: the `'b` lifetime is not known to live at least as long as `'a` | |
| 2470 | /// which means this function cannot ensure it always returns a valid reference: | |
| 2471 | /// | |
| 2472 | /// ```rust,compile_fail | |
| 2473 | /// fn select<'a, 'b>(s1: &'a str, s2: &'b str, second: bool) -> &'a str | |
| 2474 | /// { | |
| 2475 | /// if second { s2 } else { s1 } | |
| 2476 | /// } | |
| 2477 | /// ``` | |
| 2478 | /// | |
| 2479 | /// `where` can also be used to express more complicated constraints that cannot | |
| 2480 | /// be written with the `<T: Trait>` syntax: | |
| 2481 | /// | |
| 2482 | /// ```rust | |
| 2483 | /// fn first_or_default<I>(mut i: I) -> I::Item | |
| 2484 | /// where | |
| 2485 | /// I: Iterator, | |
| 2486 | /// I::Item: Default, | |
| 2487 | /// { | |
| 2488 | /// i.next().unwrap_or_else(I::Item::default) | |
| 2489 | /// } | |
| 2490 | /// | |
| 2491 | /// assert_eq!(first_or_default([1, 2, 3].into_iter()), 1); | |
| 2492 | /// assert_eq!(first_or_default(Vec::<i32>::new().into_iter()), 0); | |
| 2493 | /// ``` | |
| 2494 | /// | |
| 2495 | /// `where` is available anywhere generic and lifetime parameters are available, | |
| 2496 | /// as can be seen with the [`Cow`](../std/borrow/enum.Cow.html) type from the standard | |
| 2497 | /// library: | |
| 2498 | /// | |
| 2499 | /// ```rust | |
| 2500 | /// # #![allow(dead_code)] | |
| 2501 | /// pub enum Cow<'a, B> | |
| 2502 | /// where | |
| 2503 | /// B: ToOwned + ?Sized, | |
| 2504 | /// { | |
| 2505 | /// Borrowed(&'a B), | |
| 2506 | /// Owned(<B as ToOwned>::Owned), | |
| 2507 | /// } | |
| 2508 | /// ``` | |
| 2509 | /// | |
| 2510 | /// [RFC]: https://github.com/rust-lang/rfcs/blob/master/text/0135-where.md | |
| 2511 | mod where_keyword {} | |
| 2512 | ||
| 2513 | #[doc(keyword = "while")] | |
| 2514 | // | |
| 2515 | /// Loop while a condition is upheld. | |
| 2516 | /// | |
| 2517 | /// A `while` expression is used for predicate loops. The `while` expression runs the conditional | |
| 2518 | /// expression before running the loop body, then runs the loop body if the conditional | |
| 2519 | /// expression evaluates to `true`, or exits the loop otherwise. | |
| 2520 | /// | |
| 2521 | /// ```rust | |
| 2522 | /// let mut counter = 0; | |
| 2523 | /// | |
| 2524 | /// while counter < 10 { | |
| 2525 | /// println!("{counter}"); | |
| 2526 | /// counter += 1; | |
| 2527 | /// } | |
| 2528 | /// ``` | |
| 2529 | /// | |
| 2530 | /// Like the [`for`] expression, we can use `break` and `continue`. A `while` expression | |
| 2531 | /// cannot break with a value and always evaluates to `()` unlike [`loop`]. | |
| 2532 | /// | |
| 2533 | /// ```rust | |
| 2534 | /// let mut i = 1; | |
| 2535 | /// | |
| 2536 | /// while i < 100 { | |
| 2537 | /// i *= 2; | |
| 2538 | /// if i == 64 { | |
| 2539 | /// break; // Exit when `i` is 64. | |
| 2540 | /// } | |
| 2541 | /// } | |
| 2542 | /// ``` | |
| 2543 | /// | |
| 2544 | /// As `if` expressions have their pattern matching variant in `if let`, so too do `while` | |
| 2545 | /// expressions with `while let`. The `while let` expression matches the pattern against the | |
| 2546 | /// expression, then runs the loop body if pattern matching succeeds, or exits the loop otherwise. | |
| 2547 | /// We can use `break` and `continue` in `while let` expressions just like in `while`. | |
| 2548 | /// | |
| 2549 | /// ```rust | |
| 2550 | /// let mut counter = Some(0); | |
| 2551 | /// | |
| 2552 | /// while let Some(i) = counter { | |
| 2553 | /// if i == 10 { | |
| 2554 | /// counter = None; | |
| 2555 | /// } else { | |
| 2556 | /// println!("{i}"); | |
| 2557 | /// counter = Some (i + 1); | |
| 2558 | /// } | |
| 2559 | /// } | |
| 2560 | /// ``` | |
| 2561 | /// | |
| 2562 | /// For more information on `while` and loops in general, see the [reference]. | |
| 2563 | /// | |
| 2564 | /// See also, [`for`], [`loop`]. | |
| 2565 | /// | |
| 2566 | /// [`for`]: keyword.for.html | |
| 2567 | /// [`loop`]: keyword.loop.html | |
| 2568 | /// [reference]: ../reference/expressions/loop-expr.html#predicate-loops | |
| 2569 | mod while_keyword {} | |
| 2570 | ||
| 2571 | // 2018 Edition keywords | |
| 2572 | ||
| 2573 | #[doc(alias = "promise")] | |
| 2574 | #[doc(keyword = "async")] | |
| 2575 | // | |
| 2576 | /// Returns a [`Future`] instead of blocking the current thread. | |
| 2577 | /// | |
| 2578 | /// Use `async` in front of `fn`, `closure`, or a `block` to turn the marked code into a `Future`. | |
| 2579 | /// As such the code will not be run immediately, but will only be evaluated when the returned | |
| 2580 | /// future is [`.await`]ed. | |
| 2581 | /// | |
| 2582 | /// We have written an [async book] detailing `async`/`await` and trade-offs compared to using threads. | |
| 2583 | /// | |
| 2584 | /// ## Control Flow | |
| 2585 | /// [`return`] statements and [`?`][try operator] operators within `async` blocks do not cause | |
| 2586 | /// a return from the parent function; rather, they cause the `Future` returned by the block to | |
| 2587 | /// return with that value. | |
| 2588 | /// | |
| 2589 | /// For example, the following Rust function will return `5`, causing `x` to take the [`!` type][never type]: | |
| 2590 | /// ```rust | |
| 2591 | /// #[expect(unused_variables)] | |
| 2592 | /// fn example() -> i32 { | |
| 2593 | /// let x = { | |
| 2594 | /// return 5; | |
| 2595 | /// }; | |
| 2596 | /// } | |
| 2597 | /// ``` | |
| 2598 | /// In contrast, the following asynchronous function assigns a `Future<Output = i32>` to `x`, and | |
| 2599 | /// only returns `5` when `x` is `.await`ed: | |
| 2600 | /// ```rust | |
| 2601 | /// async fn example() -> i32 { | |
| 2602 | /// let x = async { | |
| 2603 | /// return 5; | |
| 2604 | /// }; | |
| 2605 | /// | |
| 2606 | /// x.await | |
| 2607 | /// } | |
| 2608 | /// ``` | |
| 2609 | /// Code using `?` behaves similarly - it causes the `async` block to return a [`Result`] without | |
| 2610 | /// affecting the parent function. | |
| 2611 | /// | |
| 2612 | /// Note that you cannot use `break` or `continue` from within an `async` block to affect the | |
| 2613 | /// control flow of a loop in the parent function. | |
| 2614 | /// | |
| 2615 | /// Control flow in `async` blocks is documented further in the [async book][async book blocks]. | |
| 2616 | /// | |
| 2617 | /// ## Editions | |
| 2618 | /// | |
| 2619 | /// `async` is a keyword from the 2018 edition onwards. | |
| 2620 | /// | |
| 2621 | /// It is available for use in stable Rust from version 1.39 onwards. | |
| 2622 | /// | |
| 2623 | /// [`Future`]: future::Future | |
| 2624 | /// [`.await`]: ../std/keyword.await.html | |
| 2625 | /// [async book]: https://rust-lang.github.io/async-book/ | |
| 2626 | /// [`return`]: ../std/keyword.return.html | |
| 2627 | /// [try operator]: ../reference/expressions/operator-expr.html#r-expr.try | |
| 2628 | /// [never type]: ../reference/types/never.html | |
| 2629 | /// [`Result`]: result::Result | |
| 2630 | /// [async book blocks]: https://rust-lang.github.io/async-book/part-guide/more-async-await.html#async-blocks | |
| 2631 | mod async_keyword {} | |
| 2632 | ||
| 2633 | #[doc(keyword = "await")] | |
| 2634 | // | |
| 2635 | /// Suspend execution until the result of a [`Future`] is ready. | |
| 2636 | /// | |
| 2637 | /// `.await`ing a future will suspend the current function's execution until the executor | |
| 2638 | /// has run the future to completion. | |
| 2639 | /// | |
| 2640 | /// Read the [async book] for details on how [`async`]/`await` and executors work. | |
| 2641 | /// | |
| 2642 | /// ## Editions | |
| 2643 | /// | |
| 2644 | /// `await` is a keyword from the 2018 edition onwards. | |
| 2645 | /// | |
| 2646 | /// It is available for use in stable Rust from version 1.39 onwards. | |
| 2647 | /// | |
| 2648 | /// [`Future`]: future::Future | |
| 2649 | /// [async book]: https://rust-lang.github.io/async-book/ | |
| 2650 | /// [`async`]: ../std/keyword.async.html | |
| 2651 | mod await_keyword {} | |
| 2652 | ||
| 2653 | #[doc(keyword = "dyn")] | |
| 2654 | // | |
| 2655 | /// `dyn` is a prefix of a [trait object]'s type. | |
| 2656 | /// | |
| 2657 | /// The `dyn` keyword is used to highlight that calls to methods on the associated `Trait` | |
| 2658 | /// are [dynamically dispatched]. To use the trait this way, it must be *dyn compatible*[^1]. | |
| 2659 | /// | |
| 2660 | /// Unlike generic parameters or `impl Trait`, the compiler does not know the concrete type that | |
| 2661 | /// is being passed. That is, the type has been [erased]. | |
| 2662 | /// As such, a `dyn Trait` reference contains _two_ pointers. | |
| 2663 | /// One pointer goes to the data (e.g., an instance of a struct). | |
| 2664 | /// Another pointer goes to a map of method call names to function pointers | |
| 2665 | /// (known as a virtual method table or vtable). | |
| 2666 | /// | |
| 2667 | /// At run-time, when a method needs to be called on the `dyn Trait`, the vtable is consulted to get | |
| 2668 | /// the function pointer and then that function pointer is called. | |
| 2669 | /// | |
| 2670 | /// See the Reference for more information on [trait objects][ref-trait-obj] | |
| 2671 | /// and [dyn compatibility][ref-dyn-compat]. | |
| 2672 | /// | |
| 2673 | /// ## Trade-offs | |
| 2674 | /// | |
| 2675 | /// The above indirection is the additional runtime cost of calling a function on a `dyn Trait`. | |
| 2676 | /// Methods called by dynamic dispatch generally cannot be inlined by the compiler. | |
| 2677 | /// | |
| 2678 | /// However, `dyn Trait` is likely to produce smaller code than `impl Trait` / generic parameters as | |
| 2679 | /// the method won't be duplicated for each concrete type. | |
| 2680 | /// | |
| 2681 | /// [trait object]: ../book/ch17-02-trait-objects.html | |
| 2682 | /// [dynamically dispatched]: https://en.wikipedia.org/wiki/Dynamic_dispatch | |
| 2683 | /// [ref-trait-obj]: ../reference/types/trait-object.html | |
| 2684 | /// [ref-dyn-compat]: ../reference/items/traits.html#dyn-compatibility | |
| 2685 | /// [erased]: https://en.wikipedia.org/wiki/Type_erasure | |
| 2686 | /// [^1]: Formerly known as *object safe*. | |
| 2687 | mod dyn_keyword {} | |
| 2688 | ||
| 2689 | #[doc(keyword = "union")] | |
| 2690 | // | |
| 2691 | /// The [Rust equivalent of a C-style union][union]. | |
| 2692 | /// | |
| 2693 | /// A `union` looks like a [`struct`] in terms of declaration, but all of its | |
| 2694 | /// fields exist in the same memory, superimposed over one another. For instance, | |
| 2695 | /// if we wanted some bits in memory that we sometimes interpret as a `u32` and | |
| 2696 | /// sometimes as an `f32`, we could write: | |
| 2697 | /// | |
| 2698 | /// ```rust | |
| 2699 | /// union IntOrFloat { | |
| 2700 | /// i: u32, | |
| 2701 | /// f: f32, | |
| 2702 | /// } | |
| 2703 | /// | |
| 2704 | /// let mut u = IntOrFloat { f: 1.0 }; | |
| 2705 | /// // Reading the fields of a union is always unsafe | |
| 2706 | /// assert_eq!(unsafe { u.i }, 1065353216); | |
| 2707 | /// // Updating through any of the field will modify all of them | |
| 2708 | /// u.i = 1073741824; | |
| 2709 | /// assert_eq!(unsafe { u.f }, 2.0); | |
| 2710 | /// ``` | |
| 2711 | /// | |
| 2712 | /// # Matching on unions | |
| 2713 | /// | |
| 2714 | /// It is possible to use pattern matching on `union`s. A single field name must | |
| 2715 | /// be used and it must match the name of one of the `union`'s field. | |
| 2716 | /// Like reading from a `union`, pattern matching on a `union` requires `unsafe`. | |
| 2717 | /// | |
| 2718 | /// ```rust | |
| 2719 | /// union IntOrFloat { | |
| 2720 | /// i: u32, | |
| 2721 | /// f: f32, | |
| 2722 | /// } | |
| 2723 | /// | |
| 2724 | /// let u = IntOrFloat { f: 1.0 }; | |
| 2725 | /// | |
| 2726 | /// unsafe { | |
| 2727 | /// match u { | |
| 2728 | /// IntOrFloat { i: 10 } => println!("Found exactly ten!"), | |
| 2729 | /// // Matching the field `f` provides an `f32`. | |
| 2730 | /// IntOrFloat { f } => println!("Found f = {f} !"), | |
| 2731 | /// } | |
| 2732 | /// } | |
| 2733 | /// ``` | |
| 2734 | /// | |
| 2735 | /// # References to union fields | |
| 2736 | /// | |
| 2737 | /// All fields in a `union` are all at the same place in memory which means | |
| 2738 | /// borrowing one borrows the entire `union`, for the same lifetime: | |
| 2739 | /// | |
| 2740 | /// ```rust,compile_fail,E0502 | |
| 2741 | /// union IntOrFloat { | |
| 2742 | /// i: u32, | |
| 2743 | /// f: f32, | |
| 2744 | /// } | |
| 2745 | /// | |
| 2746 | /// let mut u = IntOrFloat { f: 1.0 }; | |
| 2747 | /// | |
| 2748 | /// let f = unsafe { &u.f }; | |
| 2749 | /// // This will not compile because the field has already been borrowed, even | |
| 2750 | /// // if only immutably | |
| 2751 | /// let i = unsafe { &mut u.i }; | |
| 2752 | /// | |
| 2753 | /// *i = 10; | |
| 2754 | /// println!("f = {f} and i = {i}"); | |
| 2755 | /// ``` | |
| 2756 | /// | |
| 2757 | /// See the [Reference][union] for more information on `union`s. | |
| 2758 | /// | |
| 2759 | /// [`struct`]: keyword.struct.html | |
| 2760 | /// [union]: ../reference/items/unions.html | |
| 2761 | mod union_keyword {} |
library/core/src/lib.rs+13| ... | ... | @@ -386,4 +386,17 @@ pub mod simd { |
| 386 | 386 | pub use crate::core_simd::simd::*; |
| 387 | 387 | } |
| 388 | 388 | |
| 389 | // Include private modules that exist solely to provide rustdoc | |
| 390 | // documentation for built-in attributes. Using `include!` because rustdoc | |
| 391 | // only looks for these modules at the crate level. | |
| 392 | include!("attribute_docs.rs"); | |
| 393 | ||
| 394 | // Include a number of private modules that exist solely to provide | |
| 395 | // the rustdoc documentation for the existing keywords. Using `include!` | |
| 396 | // because rustdoc only looks for these modules at the crate level. | |
| 397 | include!("keyword_docs.rs"); | |
| 398 | ||
| 399 | // Include a number of private modules that exist solely to provide | |
| 400 | // the rustdoc documentation for primitive types. Using `include!` | |
| 401 | // because rustdoc only looks for these modules at the crate level. | |
| 389 | 402 | include!("primitive_docs.rs"); |
library/std/src/attribute_docs.rs deleted-337| ... | ... | @@ -1,337 +0,0 @@ |
| 1 | #[doc(attribute = "must_use")] | |
| 2 | // | |
| 3 | /// Warn when a value is ignored. | |
| 4 | /// | |
| 5 | /// The `must_use` attribute applies to values where simply creating or returning them is | |
| 6 | /// often not enough. If a value marked with `#[must_use]` is produced and then ignored, the | |
| 7 | /// compiler warns through the [`unused_must_use`] lint. | |
| 8 | /// | |
| 9 | /// This is most common on types that represent an important state or outcome. For example, | |
| 10 | /// [`Result`] is marked `#[must_use]` because ignoring an error value can hide a failed operation. | |
| 11 | /// In the following example, the returned `Result` is the only sign that writing the message | |
| 12 | /// might have failed: | |
| 13 | /// | |
| 14 | /// ```rust | |
| 15 | /// # #![allow(unused_must_use)] | |
| 16 | /// fn write_message() -> std::io::Result<()> { | |
| 17 | /// // Write the message... | |
| 18 | /// Ok(()) | |
| 19 | /// } | |
| 20 | /// | |
| 21 | /// write_message(); | |
| 22 | /// ``` | |
| 23 | /// | |
| 24 | /// Ignoring that `Result` triggers this warning: | |
| 25 | /// | |
| 26 | /// ```text | |
| 27 | /// warning: unused `Result` that must be used | |
| 28 | /// = note: this `Result` may be an `Err` variant, which should be handled | |
| 29 | /// = note: `#[warn(unused_must_use)]` (part of `#[warn(unused)]`) on by default | |
| 30 | /// help: use `let _ = ...` to ignore the resulting value | |
| 31 | /// ``` | |
| 32 | /// | |
| 33 | /// Future values are also `#[must_use]`: creating a future does not run it, so ignoring one often | |
| 34 | /// means the intended asynchronous work never happens. | |
| 35 | /// | |
| 36 | /// You can also place `#[must_use]` on a function, method, or trait declaration. On a function or | |
| 37 | /// method, the warning is tied to ignoring that call's return value: | |
| 38 | /// | |
| 39 | /// ```rust | |
| 40 | /// # #![allow(unused_must_use)] | |
| 41 | /// #[must_use] | |
| 42 | /// fn make_token() -> String { | |
| 43 | /// String::from("token") | |
| 44 | /// } | |
| 45 | /// | |
| 46 | /// // Ignoring this call's return value triggers `unused_must_use`. | |
| 47 | /// make_token(); | |
| 48 | /// ``` | |
| 49 | /// | |
| 50 | /// On a trait, the warning applies when a function returns an opaque type (`impl Trait`) or trait | |
| 51 | /// object (`dyn Trait`) whose bounds include that trait. This is how futures warn if you create one | |
| 52 | /// but never poll or await it, since an `async fn` returns an opaque type implementing [`Future`]. | |
| 53 | /// | |
| 54 | /// The attribute can include a message explaining what the caller should do with the value: | |
| 55 | /// | |
| 56 | /// ```rust | |
| 57 | /// # #![allow(dead_code)] | |
| 58 | /// #[must_use = "call `.finish()` to complete the operation"] | |
| 59 | /// fn start_operation() -> Operation { | |
| 60 | /// Operation | |
| 61 | /// } | |
| 62 | /// | |
| 63 | /// struct Operation; | |
| 64 | /// ``` | |
| 65 | /// | |
| 66 | /// If intentionally ignoring the value is correct, bind it to `_` or call [`drop`]: | |
| 67 | /// | |
| 68 | /// ```rust | |
| 69 | /// # #[must_use] | |
| 70 | /// # fn make_token() -> String { | |
| 71 | /// # String::from("token") | |
| 72 | /// # } | |
| 73 | /// let _ = make_token(); | |
| 74 | /// drop(make_token()); | |
| 75 | /// ``` | |
| 76 | /// | |
| 77 | /// The attribute is a warning tool, not a type-system rule. Code can still explicitly discard a | |
| 78 | /// `#[must_use]` value, and the compiler does not require callers to inspect or otherwise act on | |
| 79 | /// the value. | |
| 80 | /// | |
| 81 | /// For more information, see the Reference on [the `must_use` attribute]. | |
| 82 | /// | |
| 83 | /// [`Result`]: result::Result | |
| 84 | /// [`Future`]: future::Future | |
| 85 | /// [`unused_must_use`]: ../rustc/lints/listing/warn-by-default.html#unused-must-use | |
| 86 | /// [the `must_use` attribute]: ../reference/attributes/diagnostics.html#the-must_use-attribute | |
| 87 | mod must_use_attribute {} | |
| 88 | ||
| 89 | #[doc(attribute = "allow")] | |
| 90 | // | |
| 91 | /// The `allow` attribute suppresses lint diagnostics that would otherwise produce | |
| 92 | /// warnings or errors. It can be used on any lint or lint group (except those | |
| 93 | /// set to `forbid`). | |
| 94 | /// | |
| 95 | /// ```rust | |
| 96 | /// #[allow(dead_code)] | |
| 97 | /// fn unused_function() { | |
| 98 | /// // ... | |
| 99 | /// } | |
| 100 | /// | |
| 101 | /// fn main() { | |
| 102 | /// // `unused_function` does not generate a compiler warning. | |
| 103 | /// } | |
| 104 | /// ``` | |
| 105 | /// | |
| 106 | /// Without `#[allow(dead_code)]`, the example above would emit: | |
| 107 | /// | |
| 108 | /// ```text | |
| 109 | /// warning: function `unused_function` is never used | |
| 110 | /// --> main.rs:1:4 | |
| 111 | /// | | |
| 112 | /// 1 | fn unused_function() { | |
| 113 | /// | ^^^^^^^^^^^^^^^ | |
| 114 | /// | | |
| 115 | /// = note: `#[warn(dead_code)]` (part of `#[warn(unused)]`) on by default | |
| 116 | /// | |
| 117 | /// warning: 1 warning emitted | |
| 118 | /// ``` | |
| 119 | /// | |
| 120 | /// Multiple lints can be set to `allow` at once with commas: | |
| 121 | /// | |
| 122 | /// ```rust | |
| 123 | /// #[allow(unused_variables, unused_mut)] | |
| 124 | /// fn main() { | |
| 125 | /// let mut x: u32 = 42; | |
| 126 | /// } | |
| 127 | /// ``` | |
| 128 | /// | |
| 129 | /// This is mostly used to prevent lint warnings or errors while still under development. | |
| 130 | /// | |
| 131 | /// It cannot override a lint that has been set to `forbid`. | |
| 132 | /// | |
| 133 | /// It's also important to consider that overusing `allow` could make code harder to maintain | |
| 134 | /// and possibly hide issues. To mitigate this issue, using the `expect` attribute is preferred. | |
| 135 | /// | |
| 136 | /// `allow` can be overridden by `warn`, `deny`, and `forbid`. | |
| 137 | /// | |
| 138 | /// The lint checks supported by rustc can be found via `rustc -W help`, | |
| 139 | /// along with their default settings and are documented in [the `rustc` book]. | |
| 140 | /// | |
| 141 | /// [the `rustc` book]: ../rustc/lints/listing/index.html | |
| 142 | /// | |
| 143 | /// For more information, see the Reference on [the `allow` attribute]. | |
| 144 | /// | |
| 145 | /// [the `allow` attribute]: ../reference/attributes/diagnostics.html#lint-check-attributes | |
| 146 | mod allow_attribute {} | |
| 147 | ||
| 148 | #[doc(attribute = "cfg")] | |
| 149 | // | |
| 150 | /// Used for conditional compilation. | |
| 151 | /// | |
| 152 | /// The `cfg` attribute allows compiling an item under specific conditions, otherwise it | |
| 153 | /// will be ignored. | |
| 154 | /// | |
| 155 | /// ```rust | |
| 156 | /// // Only compiles this function for Linux. | |
| 157 | /// #[cfg(target_os = "linux")] | |
| 158 | /// fn platform_specific() { | |
| 159 | /// println!("Running on Linux"); | |
| 160 | /// } | |
| 161 | /// | |
| 162 | /// // Only compiles this function if not for Linux. | |
| 163 | /// #[cfg(not(target_os = "linux"))] | |
| 164 | /// fn platform_specific() { | |
| 165 | /// println!("Running on something else"); | |
| 166 | /// } | |
| 167 | /// ``` | |
| 168 | /// | |
| 169 | /// Depending on the platform you're targeting, only one of these two functions will be considered | |
| 170 | /// during the compilation. | |
| 171 | /// | |
| 172 | /// Conditions can also be combined with `all(...)`, `any(...)`, and `not(...)`. | |
| 173 | /// | |
| 174 | /// * `all`: True if all given predicates are true. | |
| 175 | /// * `any`: True if at least one of the given predicates is true. | |
| 176 | /// * `not`: True if the predicate is false and false if the predicate is true. | |
| 177 | /// | |
| 178 | /// ```rust | |
| 179 | /// #[cfg(all(unix, target_pointer_width = "64"))] | |
| 180 | /// fn unix_64bit() { | |
| 181 | /// } | |
| 182 | /// ``` | |
| 183 | /// | |
| 184 | /// If you want to use this mechanism in an `if` condition in your code, you | |
| 185 | /// can use the [`cfg!`] macro. To conditionally apply an attribute, | |
| 186 | /// see [`cfg_attr`]. | |
| 187 | /// | |
| 188 | /// For more information, see the Reference on [the `cfg` attribute]. | |
| 189 | /// | |
| 190 | /// [`cfg_attr`]: ../reference/conditional-compilation.html#the-cfg_attr-attribute | |
| 191 | /// [the `cfg` attribute]: ../reference/conditional-compilation.html#the-cfg-attribute | |
| 192 | mod cfg_attribute {} | |
| 193 | ||
| 194 | #[doc(attribute = "deny")] | |
| 195 | // | |
| 196 | /// Emits an error, preventing the compilation from finishing, when a lint check has failed. | |
| 197 | /// This is useful for enforcing rules or preventing certain patterns: | |
| 198 | /// | |
| 199 | /// ```rust,compile_fail | |
| 200 | /// #[deny(unused)] | |
| 201 | /// fn foo() { | |
| 202 | /// let x = 42; // Emits an error because x is unused. | |
| 203 | /// } | |
| 204 | /// ``` | |
| 205 | /// | |
| 206 | /// `deny` can be overridden by `allow`, `warn`, and `forbid`: | |
| 207 | /// | |
| 208 | /// ```rust | |
| 209 | /// #![deny(unused)] | |
| 210 | /// | |
| 211 | /// #[allow(unused)] // We override the `deny` for this function. | |
| 212 | /// fn foo() { | |
| 213 | /// let x = 42; // No lint emitted even though `x` is unused. | |
| 214 | /// } | |
| 215 | /// ``` | |
| 216 | /// | |
| 217 | /// Multiple lints can also be set to `deny` at once: | |
| 218 | /// | |
| 219 | /// ```rust,compile_fail | |
| 220 | /// #![deny(unused_imports, unused_variables)] | |
| 221 | /// use std::collections::*; | |
| 222 | /// | |
| 223 | /// fn main() { | |
| 224 | /// let mut x = 10; | |
| 225 | /// } | |
| 226 | /// ``` | |
| 227 | /// | |
| 228 | /// The lint checks supported by rustc can be found via `rustc -W help`, | |
| 229 | /// along with their default settings and are documented in [the `rustc` book]. | |
| 230 | /// | |
| 231 | /// [the `rustc` book]: ../rustc/lints/listing/index.html | |
| 232 | /// | |
| 233 | /// For more information, see the Reference on [the `deny` attribute]. | |
| 234 | /// | |
| 235 | /// [the `deny` attribute]: ../reference/attributes/diagnostics.html#lint-check-attributes | |
| 236 | mod deny_attribute {} | |
| 237 | ||
| 238 | #[doc(attribute = "forbid")] | |
| 239 | // | |
| 240 | /// Emits an error, preventing the compilation from finishing, when a lint check has failed. | |
| 241 | /// | |
| 242 | /// A lint set to `forbid` cannot be overridden by `allow` or `warn`. | |
| 243 | /// Attempting either will result in a compilation error. Writing `#[deny(...)]` on the same lint inside a | |
| 244 | /// `forbid` scope is permitted, but has no effect; the lint remains at the `forbid` level. | |
| 245 | /// | |
| 246 | /// This is useful for enforcing strict policies that should not be relaxed | |
| 247 | /// anywhere in the codebase. Example: | |
| 248 | /// | |
| 249 | /// ```rust | |
| 250 | /// #![forbid(unsafe_code)] | |
| 251 | /// | |
| 252 | /// // This would cause a compilation error if uncommented: | |
| 253 | /// // #[allow(unsafe_code)] // error: cannot override `forbid` | |
| 254 | /// ``` | |
| 255 | /// | |
| 256 | /// Multiple lints can be set to `forbid` at once: | |
| 257 | /// | |
| 258 | /// ```rust | |
| 259 | /// #![forbid(unsafe_code, unused)] | |
| 260 | /// ``` | |
| 261 | /// | |
| 262 | /// The lint checks supported by rustc can be found via `rustc -W help`, | |
| 263 | /// along with their default settings and are documented in [the `rustc` book]. | |
| 264 | /// | |
| 265 | /// [the `rustc` book]: ../rustc/lints/listing/index.html | |
| 266 | /// | |
| 267 | /// For more information, see the Reference on [the `forbid` attribute]. | |
| 268 | /// | |
| 269 | /// [the `forbid` attribute]: ../reference/attributes/diagnostics.html#lint-check-attributes | |
| 270 | mod forbid_attribute {} | |
| 271 | ||
| 272 | #[doc(attribute = "deprecated")] | |
| 273 | // | |
| 274 | /// Emits a warning during compilation when an item with this attribute is used. | |
| 275 | /// `since` and `note` are optional fields giving more detail about why the item is deprecated. | |
| 276 | /// | |
| 277 | /// * `since`: the version since when the item is deprecated. | |
| 278 | /// * `note`: the reason why an item is deprecated. | |
| 279 | /// | |
| 280 | /// Example: | |
| 281 | /// | |
| 282 | /// ```rust | |
| 283 | /// #[deprecated(since = "1.0.0", note = "Use bar instead")] | |
| 284 | /// struct Foo; | |
| 285 | /// struct Bar; | |
| 286 | /// ``` | |
| 287 | /// | |
| 288 | /// `deprecated` attribute helps developers transition away from old code by providing warnings when | |
| 289 | /// deprecated items are used. Note that during `Cargo` builds, warnings on dependencies get silenced | |
| 290 | /// by default, so you may not see a deprecation warning unless you build that dependency directly. | |
| 291 | /// | |
| 292 | /// For more information, see the Reference on [the `deprecated` attribute]. | |
| 293 | /// | |
| 294 | /// [the `deprecated` attribute]: ../reference/attributes/diagnostics.html#the-deprecated-attribute | |
| 295 | mod deprecated_attribute {} | |
| 296 | ||
| 297 | #[doc(attribute = "warn")] | |
| 298 | // | |
| 299 | /// Emits a warning during compilation when a lint check failed. | |
| 300 | /// | |
| 301 | /// Unlike `deny` or `forbid`, `warn` does not produce a hard error: the compilation continues, but | |
| 302 | /// the compiler emits a warning message. `warn` can be overridden by `allow`, `deny`, and `forbid`. | |
| 303 | /// | |
| 304 | /// Example: | |
| 305 | /// | |
| 306 | /// ```rust,compile_fail | |
| 307 | /// #![allow(unused)] | |
| 308 | /// | |
| 309 | /// #[warn(unused)] // We override the allowed `unused` lint. | |
| 310 | /// fn foo() { | |
| 311 | /// // This lint warns by default even without #[warn(unused)] being explicitly set | |
| 312 | /// let x = 42; // warning: unused variable `x` | |
| 313 | /// } | |
| 314 | /// ``` | |
| 315 | /// | |
| 316 | /// | |
| 317 | /// Many lints, including `unused`, are already set to `warn` by default so this attribute is | |
| 318 | /// mainly useful for lints that are normally `allow` by default. | |
| 319 | /// | |
| 320 | /// Multiple lints can be set to `warn` at once: | |
| 321 | /// | |
| 322 | /// ```rust,compile_fail | |
| 323 | /// #[warn(unused_mut, unused_variables)] | |
| 324 | /// fn main() { | |
| 325 | /// let mut x = 42; | |
| 326 | /// } | |
| 327 | /// ``` | |
| 328 | /// | |
| 329 | /// The lint checks supported by rustc can be found via `rustc -W help`, | |
| 330 | /// along with their default settings and are documented in [the `rustc` book]. | |
| 331 | /// | |
| 332 | /// [the `rustc` book]: ../rustc/lints/listing/index.html | |
| 333 | /// | |
| 334 | /// For more information, see the Reference on [the `warn` attribute]. | |
| 335 | /// | |
| 336 | /// [the `warn` attribute]: ../reference/attributes/diagnostics.html#lint-check-attributes | |
| 337 | mod warn_attribute {} |
library/std/src/keyword_docs.rs deleted-2770| ... | ... | @@ -1,2770 +0,0 @@ |
| 1 | #[doc(keyword = "as")] | |
| 2 | // | |
| 3 | /// Cast between types, rename an import, or qualify paths to associated items. | |
| 4 | /// | |
| 5 | /// # Type casting | |
| 6 | /// | |
| 7 | /// `as` is most commonly used to turn primitive types into other primitive types, but it has other | |
| 8 | /// uses that include turning pointers into addresses, addresses into pointers, and pointers into | |
| 9 | /// other pointers. | |
| 10 | /// | |
| 11 | /// ```rust | |
| 12 | /// let thing1: u8 = 89.0 as u8; | |
| 13 | /// assert_eq!('B' as u32, 66); | |
| 14 | /// assert_eq!(thing1 as char, 'Y'); | |
| 15 | /// let thing2: f32 = thing1 as f32 + 10.5; | |
| 16 | /// assert_eq!(true as u8 + thing2 as u8, 100); | |
| 17 | /// ``` | |
| 18 | /// | |
| 19 | /// In general, any cast that can be performed via ascribing the type can also be done using `as`, | |
| 20 | /// so instead of writing `let x: u32 = 123`, you can write `let x = 123 as u32` (note: `let x: u32 | |
| 21 | /// = 123` would be best in that situation). The same is not true in the other direction, however; | |
| 22 | /// explicitly using `as` allows a few more coercions that aren't allowed implicitly, such as | |
| 23 | /// changing the type of a raw pointer or turning closures into raw pointers. | |
| 24 | /// | |
| 25 | /// `as` can be seen as the primitive for `From` and `Into`: `as` only works with primitives | |
| 26 | /// (`u8`, `bool`, `str`, pointers, ...) whereas `From` and `Into` also works with types like | |
| 27 | /// `String` or `Vec`. | |
| 28 | /// | |
| 29 | /// `as` can also be used with the `_` placeholder when the destination type can be inferred. Note | |
| 30 | /// that this can cause inference breakage and usually such code should use an explicit type for | |
| 31 | /// both clarity and stability. This is most useful when converting pointers using `as *const _` or | |
| 32 | /// `as *mut _` though the [`cast`][const-cast] method is recommended over `as *const _` and it is | |
| 33 | /// [the same][mut-cast] for `as *mut _`: those methods make the intent clearer. | |
| 34 | /// | |
| 35 | /// # Renaming imports | |
| 36 | /// | |
| 37 | /// `as` is also used to rename imports in [`use`] and [`extern crate`][`crate`] statements: | |
| 38 | /// | |
| 39 | /// ``` | |
| 40 | /// # #[allow(unused_imports)] | |
| 41 | /// use std::{mem as memory, net as network}; | |
| 42 | /// // Now you can use the names `memory` and `network` to refer to `std::mem` and `std::net`. | |
| 43 | /// ``` | |
| 44 | /// | |
| 45 | /// # Qualifying paths | |
| 46 | /// | |
| 47 | /// You'll also find with `From` and `Into`, and indeed all traits, that `as` is used for the | |
| 48 | /// _fully qualified path_, a means of disambiguating associated items, i.e. functions, | |
| 49 | /// constants, and types. For example, if you have a type which implements two traits with identical | |
| 50 | /// method names (e.g. `Into::<u32>::into` and `Into::<u64>::into`), you can clarify which method | |
| 51 | /// you'll use with `<MyThing as Into<u32>>::into(my_thing)`[^as-use-from]. This is quite verbose, | |
| 52 | /// but fortunately, Rust's type inference usually saves you from needing this, although it is | |
| 53 | /// occasionally necessary, especially with methods that return a generic type like `Into::into` or | |
| 54 | /// methods that don't take `self`. It's more common to use in macros where it can provide necessary | |
| 55 | /// hygiene. | |
| 56 | /// | |
| 57 | /// [^as-use-from]: You should probably never use this syntax with `Into` and instead write | |
| 58 | /// `T::from(my_thing)`. It just happens that there aren't any great examples for this syntax in | |
| 59 | /// the standard library. Also, at time of writing, the compiler tends to suggest fully-qualified | |
| 60 | /// paths to fix ambiguous `Into::into` calls, so the example should hopefully be familiar. | |
| 61 | /// | |
| 62 | /// # Further reading | |
| 63 | /// | |
| 64 | /// For more information on what `as` is capable of, see the Reference on [type cast expressions], | |
| 65 | /// [renaming imported entities], [renaming `extern` crates] | |
| 66 | /// and [qualified paths]. | |
| 67 | /// | |
| 68 | /// [type cast expressions]: ../reference/expressions/operator-expr.html#type-cast-expressions | |
| 69 | /// [renaming imported entities]: https://doc.rust-lang.org/reference/items/use-declarations.html#as-renames | |
| 70 | /// [renaming `extern` crates]: https://doc.rust-lang.org/reference/items/extern-crates.html#r-items.extern-crate.as | |
| 71 | /// [qualified paths]: ../reference/paths.html#qualified-paths | |
| 72 | /// [`crate`]: keyword.crate.html | |
| 73 | /// [`use`]: keyword.use.html | |
| 74 | /// [const-cast]: pointer::cast | |
| 75 | /// [mut-cast]: primitive.pointer.html#method.cast-1 | |
| 76 | mod as_keyword {} | |
| 77 | ||
| 78 | #[doc(keyword = "break")] | |
| 79 | // | |
| 80 | /// Exit early from a loop or labelled block. | |
| 81 | /// | |
| 82 | /// When `break` is encountered, execution of the associated loop body is | |
| 83 | /// immediately terminated. | |
| 84 | /// | |
| 85 | /// ```rust | |
| 86 | /// let mut last = 0; | |
| 87 | /// | |
| 88 | /// for x in 1..100 { | |
| 89 | /// if x > 12 { | |
| 90 | /// break; | |
| 91 | /// } | |
| 92 | /// last = x; | |
| 93 | /// } | |
| 94 | /// | |
| 95 | /// assert_eq!(last, 12); | |
| 96 | /// println!("{last}"); | |
| 97 | /// ``` | |
| 98 | /// | |
| 99 | /// A break expression is normally associated with the innermost loop enclosing the | |
| 100 | /// `break` but a label can be used to specify which enclosing loop is affected. | |
| 101 | /// | |
| 102 | /// ```rust | |
| 103 | /// 'outer: for i in 1..=5 { | |
| 104 | /// println!("outer iteration (i): {i}"); | |
| 105 | /// | |
| 106 | /// '_inner: for j in 1..=200 { | |
| 107 | /// println!(" inner iteration (j): {j}"); | |
| 108 | /// if j >= 3 { | |
| 109 | /// // breaks from inner loop, lets outer loop continue. | |
| 110 | /// break; | |
| 111 | /// } | |
| 112 | /// if i >= 2 { | |
| 113 | /// // breaks from outer loop, and directly to "Bye". | |
| 114 | /// break 'outer; | |
| 115 | /// } | |
| 116 | /// } | |
| 117 | /// } | |
| 118 | /// println!("Bye."); | |
| 119 | /// ``` | |
| 120 | /// | |
| 121 | /// When associated with `loop`, a break expression may be used to return a value from that loop. | |
| 122 | /// This is only valid with `loop` and not with any other type of loop. | |
| 123 | /// If no value is specified for `break;` it returns `()`. | |
| 124 | /// Every `break` within a loop must return the same type. | |
| 125 | /// | |
| 126 | /// ```rust | |
| 127 | /// let (mut a, mut b) = (1, 1); | |
| 128 | /// let result = loop { | |
| 129 | /// if b > 10 { | |
| 130 | /// break b; | |
| 131 | /// } | |
| 132 | /// let c = a + b; | |
| 133 | /// a = b; | |
| 134 | /// b = c; | |
| 135 | /// }; | |
| 136 | /// // first number in Fibonacci sequence over 10: | |
| 137 | /// assert_eq!(result, 13); | |
| 138 | /// println!("{result}"); | |
| 139 | /// ``` | |
| 140 | /// | |
| 141 | /// It is also possible to exit from any *labelled* block returning the value early. | |
| 142 | /// If no value is specified for `break;` it returns `()`. | |
| 143 | /// | |
| 144 | /// ```rust | |
| 145 | /// let inputs = vec!["Cow", "Cat", "Dog", "Snake", "Cod"]; | |
| 146 | /// | |
| 147 | /// let mut results = vec![]; | |
| 148 | /// for input in inputs { | |
| 149 | /// let result = 'filter: { | |
| 150 | /// if input.len() > 3 { | |
| 151 | /// break 'filter Err("Too long"); | |
| 152 | /// }; | |
| 153 | /// | |
| 154 | /// if !input.contains("C") { | |
| 155 | /// break 'filter Err("No Cs"); | |
| 156 | /// }; | |
| 157 | /// | |
| 158 | /// Ok(input.to_uppercase()) | |
| 159 | /// }; | |
| 160 | /// | |
| 161 | /// results.push(result); | |
| 162 | /// } | |
| 163 | /// | |
| 164 | /// // [Ok("COW"), Ok("CAT"), Err("No Cs"), Err("Too long"), Ok("COD")] | |
| 165 | /// println!("{:?}", results) | |
| 166 | /// ``` | |
| 167 | /// | |
| 168 | /// For more details consult the [Reference on "break expression"] and the [Reference on "break and | |
| 169 | /// loop values"]. | |
| 170 | /// | |
| 171 | /// [Reference on "break expression"]: ../reference/expressions/loop-expr.html#break-expressions | |
| 172 | /// [Reference on "break and loop values"]: | |
| 173 | /// ../reference/expressions/loop-expr.html#break-and-loop-values | |
| 174 | mod break_keyword {} | |
| 175 | ||
| 176 | #[doc(keyword = "const")] | |
| 177 | // | |
| 178 | /// Compile-time constants, compile-time blocks, compile-time evaluable functions, and raw pointers. | |
| 179 | /// | |
| 180 | /// ## Compile-time constants | |
| 181 | /// | |
| 182 | /// Sometimes a certain value is used many times throughout a program, and it can become | |
| 183 | /// inconvenient to copy it over and over. What's more, it's not always possible or desirable to | |
| 184 | /// make it a variable that gets carried around to each function that needs it. In these cases, the | |
| 185 | /// `const` keyword provides a convenient alternative to code duplication: | |
| 186 | /// | |
| 187 | /// ```rust | |
| 188 | /// const THING: u32 = 0xABAD1DEA; | |
| 189 | /// | |
| 190 | /// let foo = 123 + THING; | |
| 191 | /// ``` | |
| 192 | /// | |
| 193 | /// Constants must be explicitly typed; unlike with `let`, you can't ignore their type and let the | |
| 194 | /// compiler figure it out. Any constant value can be defined in a `const`, which in practice happens | |
| 195 | /// to be most things that would be reasonable to have in a constant (barring `const fn`s). For | |
| 196 | /// example, you can't have a [`File`] as a `const`. | |
| 197 | /// | |
| 198 | /// [`File`]: crate::fs::File | |
| 199 | /// | |
| 200 | /// The only lifetime allowed in a constant is `'static`, which is the lifetime that encompasses | |
| 201 | /// all others in a Rust program. For example, if you wanted to define a constant string, it would | |
| 202 | /// look like this: | |
| 203 | /// | |
| 204 | /// ```rust | |
| 205 | /// const WORDS: &'static str = "hello rust!"; | |
| 206 | /// ``` | |
| 207 | /// | |
| 208 | /// Thanks to static lifetime elision, you usually don't have to explicitly use `'static`: | |
| 209 | /// | |
| 210 | /// ```rust | |
| 211 | /// const WORDS: &str = "hello convenience!"; | |
| 212 | /// ``` | |
| 213 | /// | |
| 214 | /// `const` items look remarkably similar to `static` items, which introduces some confusion as | |
| 215 | /// to which one should be used at which times. To put it simply, constants are inlined wherever | |
| 216 | /// they're used, making using them identical to simply replacing the name of the `const` with its | |
| 217 | /// value. Static variables, on the other hand, point to a single location in memory, which all | |
| 218 | /// accesses share. This means that, unlike with constants, they can't have destructors, and act as | |
| 219 | /// a single value across the entire codebase. | |
| 220 | /// | |
| 221 | /// Constants, like statics, should always be in `SCREAMING_SNAKE_CASE`. | |
| 222 | /// | |
| 223 | /// For more detail on `const`, see the [Rust Book] or the [Reference]. | |
| 224 | /// | |
| 225 | /// ## Compile-time blocks | |
| 226 | /// | |
| 227 | /// The `const` keyword can also be used to define a block of code that is evaluated at compile time. | |
| 228 | /// This is useful for ensuring certain computations are completed before optimizations happen, as well as | |
| 229 | /// before runtime. For more details, see the [Reference][const-blocks]. | |
| 230 | /// | |
| 231 | /// ## Compile-time evaluable functions | |
| 232 | /// | |
| 233 | /// The other main use of the `const` keyword is in `const fn`. This marks a function as being | |
| 234 | /// callable in the body of a `const` or `static` item and in array initializers (commonly called | |
| 235 | /// "const contexts"). `const fn` are restricted in the set of operations they can perform, to | |
| 236 | /// ensure that they can be evaluated at compile-time. See the [Reference][const-eval] for more | |
| 237 | /// detail. | |
| 238 | /// | |
| 239 | /// Turning a `fn` into a `const fn` has no effect on run-time uses of that function. | |
| 240 | /// | |
| 241 | /// ## raw pointers | |
| 242 | /// | |
| 243 | /// The `const` keyword is also used in raw pointers in combination with `mut`, as seen in `*const | |
| 244 | /// T` and `*mut T`. More about `const` as used in raw pointers can be read at the Rust docs for the [pointer primitive]. | |
| 245 | /// | |
| 246 | /// [pointer primitive]: pointer | |
| 247 | /// [Rust Book]: ../book/ch03-01-variables-and-mutability.html#constants | |
| 248 | /// [Reference]: ../reference/items/constant-items.html | |
| 249 | /// [const-blocks]: ../reference/expressions/block-expr.html#const-blocks | |
| 250 | /// [const-eval]: ../reference/const_eval.html | |
| 251 | mod const_keyword {} | |
| 252 | ||
| 253 | #[doc(keyword = "continue")] | |
| 254 | // | |
| 255 | /// Skip to the next iteration of a loop. | |
| 256 | /// | |
| 257 | /// When `continue` is encountered, the current iteration is terminated, returning control to the | |
| 258 | /// loop head, typically continuing with the next iteration. | |
| 259 | /// | |
| 260 | /// ```rust | |
| 261 | /// // Printing odd numbers by skipping even ones | |
| 262 | /// for number in 1..=10 { | |
| 263 | /// if number % 2 == 0 { | |
| 264 | /// continue; | |
| 265 | /// } | |
| 266 | /// println!("{number}"); | |
| 267 | /// } | |
| 268 | /// ``` | |
| 269 | /// | |
| 270 | /// Like `break`, `continue` is normally associated with the innermost enclosing loop, but labels | |
| 271 | /// may be used to specify the affected loop. | |
| 272 | /// | |
| 273 | /// ```rust | |
| 274 | /// // Print Odd numbers under 30 with unit <= 5 | |
| 275 | /// 'tens: for ten in 0..3 { | |
| 276 | /// '_units: for unit in 0..=9 { | |
| 277 | /// if unit % 2 == 0 { | |
| 278 | /// continue; | |
| 279 | /// } | |
| 280 | /// if unit > 5 { | |
| 281 | /// continue 'tens; | |
| 282 | /// } | |
| 283 | /// println!("{}", ten * 10 + unit); | |
| 284 | /// } | |
| 285 | /// } | |
| 286 | /// ``` | |
| 287 | /// | |
| 288 | /// See [continue expressions] from the reference for more details. | |
| 289 | /// | |
| 290 | /// [continue expressions]: ../reference/expressions/loop-expr.html#continue-expressions | |
| 291 | mod continue_keyword {} | |
| 292 | ||
| 293 | #[doc(keyword = "crate")] | |
| 294 | // | |
| 295 | /// A Rust binary or library. | |
| 296 | /// | |
| 297 | /// The primary use of the `crate` keyword is as a part of `extern crate` declarations, which are | |
| 298 | /// used to specify a dependency on a crate external to the one it's declared in. Crates are the | |
| 299 | /// fundamental compilation unit of Rust code, and can be seen as libraries or projects. More can | |
| 300 | /// be read about crates in the [Reference]. | |
| 301 | /// | |
| 302 | /// ```rust ignore | |
| 303 | /// extern crate rand; | |
| 304 | /// extern crate my_crate as thing; | |
| 305 | /// extern crate std; // implicitly added to the root of every Rust project | |
| 306 | /// ``` | |
| 307 | /// | |
| 308 | /// The `as` keyword can be used to change what the crate is referred to as in your project. If a | |
| 309 | /// crate name includes a dash, it is implicitly imported with the dashes replaced by underscores. | |
| 310 | /// | |
| 311 | /// `crate` can also be used as in conjunction with `pub` to signify that the item it's attached to | |
| 312 | /// is public only to other members of the same crate it's in. | |
| 313 | /// | |
| 314 | /// ```rust | |
| 315 | /// # #[allow(unused_imports)] | |
| 316 | /// pub(crate) use std::io::Error as IoError; | |
| 317 | /// pub(crate) enum CoolMarkerType { } | |
| 318 | /// pub struct PublicThing { | |
| 319 | /// pub(crate) semi_secret_thing: bool, | |
| 320 | /// } | |
| 321 | /// ``` | |
| 322 | /// | |
| 323 | /// `crate` is also used to represent the absolute path of a module, where `crate` refers to the | |
| 324 | /// root of the current crate. For instance, `crate::foo::bar` refers to the name `bar` inside the | |
| 325 | /// module `foo`, from anywhere else in the same crate. | |
| 326 | /// | |
| 327 | /// [Reference]: ../reference/items/extern-crates.html | |
| 328 | mod crate_keyword {} | |
| 329 | ||
| 330 | #[doc(keyword = "else")] | |
| 331 | // | |
| 332 | /// What expression to evaluate when an [`if`] condition evaluates to [`false`]. | |
| 333 | /// | |
| 334 | /// `else` expressions are optional. When no else expressions are supplied it is assumed to evaluate | |
| 335 | /// to the unit type `()`. | |
| 336 | /// | |
| 337 | /// The type that the `else` blocks evaluate to must be compatible with the type that the `if` block | |
| 338 | /// evaluates to. | |
| 339 | /// | |
| 340 | /// As can be seen below, `else` must be followed by either: `if`, `if let`, or a block `{}` and it | |
| 341 | /// will return the value of that expression. | |
| 342 | /// | |
| 343 | /// ```rust | |
| 344 | /// let result = if true == false { | |
| 345 | /// "oh no" | |
| 346 | /// } else if "something" == "other thing" { | |
| 347 | /// "oh dear" | |
| 348 | /// } else if let Some(200) = "blarg".parse::<i32>().ok() { | |
| 349 | /// "uh oh" | |
| 350 | /// } else { | |
| 351 | /// println!("Sneaky side effect."); | |
| 352 | /// "phew, nothing's broken" | |
| 353 | /// }; | |
| 354 | /// ``` | |
| 355 | /// | |
| 356 | /// Here's another example but here we do not try and return an expression: | |
| 357 | /// | |
| 358 | /// ```rust | |
| 359 | /// if true == false { | |
| 360 | /// println!("oh no"); | |
| 361 | /// } else if "something" == "other thing" { | |
| 362 | /// println!("oh dear"); | |
| 363 | /// } else if let Some(200) = "blarg".parse::<i32>().ok() { | |
| 364 | /// println!("uh oh"); | |
| 365 | /// } else { | |
| 366 | /// println!("phew, nothing's broken"); | |
| 367 | /// } | |
| 368 | /// ``` | |
| 369 | /// | |
| 370 | /// The above is _still_ an expression but it will always evaluate to `()`. | |
| 371 | /// | |
| 372 | /// There is possibly no limit to the number of `else` blocks that could follow an `if` expression | |
| 373 | /// however if you have several then a [`match`] expression might be preferable. | |
| 374 | /// | |
| 375 | /// Read more about control flow in the [Rust Book]. | |
| 376 | /// | |
| 377 | /// [Rust Book]: ../book/ch03-05-control-flow.html#handling-multiple-conditions-with-else-if | |
| 378 | /// [`match`]: keyword.match.html | |
| 379 | /// [`false`]: keyword.false.html | |
| 380 | /// [`if`]: keyword.if.html | |
| 381 | mod else_keyword {} | |
| 382 | ||
| 383 | #[doc(keyword = "enum")] | |
| 384 | // | |
| 385 | /// A type that can be any one of several variants. | |
| 386 | /// | |
| 387 | /// Enums in Rust are similar to those of other compiled languages like C, but have important | |
| 388 | /// differences that make them considerably more powerful. What Rust calls enums are more commonly | |
| 389 | /// known as [Algebraic Data Types][ADT] if you're coming from a functional programming background. | |
| 390 | /// The important detail is that each enum variant can have data to go along with it. | |
| 391 | /// | |
| 392 | /// ```rust | |
| 393 | /// # struct Coord; | |
| 394 | /// enum SimpleEnum { | |
| 395 | /// FirstVariant, | |
| 396 | /// SecondVariant, | |
| 397 | /// ThirdVariant, | |
| 398 | /// } | |
| 399 | /// | |
| 400 | /// enum Location { | |
| 401 | /// Unknown, | |
| 402 | /// Anonymous, | |
| 403 | /// Known(Coord), | |
| 404 | /// } | |
| 405 | /// | |
| 406 | /// enum ComplexEnum { | |
| 407 | /// Nothing, | |
| 408 | /// Something(u32), | |
| 409 | /// LotsOfThings { | |
| 410 | /// usual_struct_stuff: bool, | |
| 411 | /// blah: String, | |
| 412 | /// } | |
| 413 | /// } | |
| 414 | /// | |
| 415 | /// enum EmptyEnum { } | |
| 416 | /// ``` | |
| 417 | /// | |
| 418 | /// The first enum shown is the usual kind of enum you'd find in a C-style language. The second | |
| 419 | /// shows off a hypothetical example of something storing location data, with `Coord` being any | |
| 420 | /// other type that's needed, for example a struct. The third example demonstrates the kind of | |
| 421 | /// data a variant can store, ranging from nothing, to a tuple, to a struct-like variant. | |
| 422 | /// | |
| 423 | /// Instantiating enum variants involves explicitly using the enum's name as its namespace, | |
| 424 | /// followed by one of its variants. `SimpleEnum::SecondVariant` would be an example from above. | |
| 425 | /// When data follows along with a variant, such as with rust's built-in [`Option`] type, the data | |
| 426 | /// is added as the type describes, for example `Option::Some(123)`. The same follows with | |
| 427 | /// struct-like variants, with things looking like `ComplexEnum::LotsOfThings { usual_struct_stuff: | |
| 428 | /// true, blah: "hello!".to_string(), }`. Empty Enums are similar to [`!`] in that they cannot be | |
| 429 | /// instantiated at all, and are used mainly to mess with the type system in interesting ways. | |
| 430 | /// | |
| 431 | /// For more information, take a look at the [Rust Book] or the [Reference] | |
| 432 | /// | |
| 433 | /// [ADT]: https://en.wikipedia.org/wiki/Algebraic_data_type | |
| 434 | /// [Rust Book]: ../book/ch06-01-defining-an-enum.html | |
| 435 | /// [Reference]: ../reference/items/enumerations.html | |
| 436 | mod enum_keyword {} | |
| 437 | ||
| 438 | #[doc(keyword = "extern")] | |
| 439 | // | |
| 440 | /// Link to or import external code. | |
| 441 | /// | |
| 442 | /// The `extern` keyword is used in two places in Rust. One is in conjunction with the [`crate`] | |
| 443 | /// keyword to make your Rust code aware of other Rust crates in your project, i.e., `extern crate | |
| 444 | /// lazy_static;`. The other use is in foreign function interfaces (FFI). | |
| 445 | /// | |
| 446 | /// `extern` is used in two different contexts within FFI. The first is in the form of external | |
| 447 | /// blocks, for declaring function interfaces that Rust code can call foreign code by. This use | |
| 448 | /// of `extern` is unsafe, since we are asserting to the compiler that all function declarations | |
| 449 | /// are correct. If they are not, using these items may lead to undefined behavior. | |
| 450 | /// | |
| 451 | /// ```rust ignore | |
| 452 | /// // SAFETY: The function declarations given below are in | |
| 453 | /// // line with the header files of `my_c_library`. | |
| 454 | /// #[link(name = "my_c_library")] | |
| 455 | /// unsafe extern "C" { | |
| 456 | /// fn my_c_function(x: i32) -> bool; | |
| 457 | /// } | |
| 458 | /// ``` | |
| 459 | /// | |
| 460 | /// This code would attempt to link with `libmy_c_library.so` on unix-like systems and | |
| 461 | /// `my_c_library.dll` on Windows at runtime, and panic if it can't find something to link to. Rust | |
| 462 | /// code could then use `my_c_function` as if it were any other unsafe Rust function. Working with | |
| 463 | /// non-Rust languages and FFI is inherently unsafe, so wrappers are usually built around C APIs. | |
| 464 | /// | |
| 465 | /// The mirror use case of FFI is also done via the `extern` keyword: | |
| 466 | /// | |
| 467 | /// ```rust | |
| 468 | /// #[unsafe(no_mangle)] | |
| 469 | /// pub extern "C" fn callable_from_c(x: i32) -> bool { | |
| 470 | /// x % 3 == 0 | |
| 471 | /// } | |
| 472 | /// ``` | |
| 473 | /// | |
| 474 | /// If compiled as a dylib, the resulting .so could then be linked to from a C library, and the | |
| 475 | /// function could be used as if it was from any other library. | |
| 476 | /// | |
| 477 | /// For more information on FFI, check the [Rust book] or the [Reference]. | |
| 478 | /// | |
| 479 | /// [Rust book]: | |
| 480 | /// ../book/ch19-01-unsafe-rust.html#using-extern-functions-to-call-external-code | |
| 481 | /// [Reference]: ../reference/items/external-blocks.html | |
| 482 | /// [`crate`]: keyword.crate.html | |
| 483 | mod extern_keyword {} | |
| 484 | ||
| 485 | #[doc(keyword = "false")] | |
| 486 | // | |
| 487 | /// A value of type [`bool`] representing logical **false**. | |
| 488 | /// | |
| 489 | /// `false` is the logical opposite of [`true`]. | |
| 490 | /// | |
| 491 | /// See the documentation for [`true`] for more information. | |
| 492 | /// | |
| 493 | /// [`true`]: keyword.true.html | |
| 494 | mod false_keyword {} | |
| 495 | ||
| 496 | #[doc(keyword = "fn")] | |
| 497 | // | |
| 498 | /// A function or function pointer. | |
| 499 | /// | |
| 500 | /// Functions are the primary way code is executed within Rust. Function blocks, usually just | |
| 501 | /// called functions, can be defined in a variety of different places and be assigned many | |
| 502 | /// different attributes and modifiers. | |
| 503 | /// | |
| 504 | /// Standalone functions that just sit within a module not attached to anything else are common, | |
| 505 | /// but most functions will end up being inside [`impl`] blocks, either on another type itself, or | |
| 506 | /// as a trait impl for that type. | |
| 507 | /// | |
| 508 | /// ```rust | |
| 509 | /// fn standalone_function() { | |
| 510 | /// // code | |
| 511 | /// } | |
| 512 | /// | |
| 513 | /// pub fn public_thing(argument: bool) -> String { | |
| 514 | /// // code | |
| 515 | /// # "".to_string() | |
| 516 | /// } | |
| 517 | /// | |
| 518 | /// struct Thing { | |
| 519 | /// foo: i32, | |
| 520 | /// } | |
| 521 | /// | |
| 522 | /// impl Thing { | |
| 523 | /// pub fn new() -> Self { | |
| 524 | /// Self { | |
| 525 | /// foo: 42, | |
| 526 | /// } | |
| 527 | /// } | |
| 528 | /// } | |
| 529 | /// ``` | |
| 530 | /// | |
| 531 | /// In addition to presenting fixed types in the form of `fn name(arg: type, ..) -> return_type`, | |
| 532 | /// functions can also declare a list of type parameters along with trait bounds that they fall | |
| 533 | /// into. | |
| 534 | /// | |
| 535 | /// ```rust | |
| 536 | /// fn generic_function<T: Clone>(x: T) -> (T, T, T) { | |
| 537 | /// (x.clone(), x.clone(), x.clone()) | |
| 538 | /// } | |
| 539 | /// | |
| 540 | /// fn generic_where<T>(x: T) -> T | |
| 541 | /// where T: std::ops::Add<Output = T> + Copy | |
| 542 | /// { | |
| 543 | /// x + x + x | |
| 544 | /// } | |
| 545 | /// ``` | |
| 546 | /// | |
| 547 | /// Declaring trait bounds in the angle brackets is functionally identical to using a `where` | |
| 548 | /// clause. It's up to the programmer to decide which works better in each situation, but `where` | |
| 549 | /// tends to be better when things get longer than one line. | |
| 550 | /// | |
| 551 | /// Along with being made public via `pub`, `fn` can also have an [`extern`] added for use in | |
| 552 | /// FFI. | |
| 553 | /// | |
| 554 | /// For more information on the various types of functions and how they're used, consult the [Rust | |
| 555 | /// book] or the [Reference]. | |
| 556 | /// | |
| 557 | /// [`impl`]: keyword.impl.html | |
| 558 | /// [`extern`]: keyword.extern.html | |
| 559 | /// [Rust book]: ../book/ch03-03-how-functions-work.html | |
| 560 | /// [Reference]: ../reference/items/functions.html | |
| 561 | mod fn_keyword {} | |
| 562 | ||
| 563 | #[doc(keyword = "for")] | |
| 564 | // | |
| 565 | /// Iteration with [`in`], trait implementation with [`impl`], or [higher-ranked trait bounds] | |
| 566 | /// (`for<'a>`). | |
| 567 | /// | |
| 568 | /// The `for` keyword is used in many syntactic locations: | |
| 569 | /// | |
| 570 | /// * `for` is used in for-in-loops (see below). | |
| 571 | /// * `for` is used when implementing traits as in `impl Trait for Type` (see [`impl`] for more info | |
| 572 | /// on that). | |
| 573 | /// * `for` is also used for [higher-ranked trait bounds] as in `for<'a> &'a T: PartialEq<i32>`. | |
| 574 | /// | |
| 575 | /// for-in-loops, or to be more precise, iterator loops, are a simple syntactic sugar over a common | |
| 576 | /// practice within Rust, which is to loop over anything that implements [`IntoIterator`] until the | |
| 577 | /// iterator returned by `.into_iter()` returns `None` (or the loop body uses `break`). | |
| 578 | /// | |
| 579 | /// ```rust | |
| 580 | /// for i in 0..5 { | |
| 581 | /// println!("{}", i * 2); | |
| 582 | /// } | |
| 583 | /// | |
| 584 | /// for i in std::iter::repeat(5) { | |
| 585 | /// println!("turns out {i} never stops being 5"); | |
| 586 | /// break; // would loop forever otherwise | |
| 587 | /// } | |
| 588 | /// | |
| 589 | /// 'outer: for x in 5..50 { | |
| 590 | /// for y in 0..10 { | |
| 591 | /// if x == y { | |
| 592 | /// break 'outer; | |
| 593 | /// } | |
| 594 | /// } | |
| 595 | /// } | |
| 596 | /// ``` | |
| 597 | /// | |
| 598 | /// As shown in the example above, `for` loops (along with all other loops) can be tagged, using | |
| 599 | /// similar syntax to lifetimes (only visually similar, entirely distinct in practice). Giving the | |
| 600 | /// same tag to `break` breaks the tagged loop, which is useful for inner loops. It is definitely | |
| 601 | /// not a goto. | |
| 602 | /// | |
| 603 | /// A `for` loop expands as shown: | |
| 604 | /// | |
| 605 | /// ```rust | |
| 606 | /// # fn code() { } | |
| 607 | /// # let iterator = 0..2; | |
| 608 | /// for loop_variable in iterator { | |
| 609 | /// code() | |
| 610 | /// } | |
| 611 | /// ``` | |
| 612 | /// | |
| 613 | /// ```rust | |
| 614 | /// # fn code() { } | |
| 615 | /// # let iterator = 0..2; | |
| 616 | /// { | |
| 617 | /// let result = match IntoIterator::into_iter(iterator) { | |
| 618 | /// mut iter => loop { | |
| 619 | /// match iter.next() { | |
| 620 | /// None => break, | |
| 621 | /// Some(loop_variable) => { code(); }, | |
| 622 | /// }; | |
| 623 | /// }, | |
| 624 | /// }; | |
| 625 | /// result | |
| 626 | /// } | |
| 627 | /// ``` | |
| 628 | /// | |
| 629 | /// More details on the functionality shown can be seen at the [`IntoIterator`] docs. | |
| 630 | /// | |
| 631 | /// For more information on for-loops, see the [Rust book] or the [Reference]. | |
| 632 | /// | |
| 633 | /// See also, [`loop`], [`while`]. | |
| 634 | /// | |
| 635 | /// [`in`]: keyword.in.html | |
| 636 | /// [`impl`]: keyword.impl.html | |
| 637 | /// [`loop`]: keyword.loop.html | |
| 638 | /// [`while`]: keyword.while.html | |
| 639 | /// [higher-ranked trait bounds]: ../reference/trait-bounds.html#higher-ranked-trait-bounds | |
| 640 | /// [Rust book]: | |
| 641 | /// ../book/ch03-05-control-flow.html#looping-through-a-collection-with-for | |
| 642 | /// [Reference]: ../reference/expressions/loop-expr.html#iterator-loops | |
| 643 | mod for_keyword {} | |
| 644 | ||
| 645 | #[doc(keyword = "if")] | |
| 646 | // | |
| 647 | /// Evaluate a block if a condition holds. | |
| 648 | /// | |
| 649 | /// `if` is a familiar construct to most programmers, and is the main way you'll often do logic in | |
| 650 | /// your code. However, unlike in most languages, `if` blocks can also act as expressions. | |
| 651 | /// | |
| 652 | /// ```rust | |
| 653 | /// # let rude = true; | |
| 654 | /// if 1 == 2 { | |
| 655 | /// println!("whoops, mathematics broke"); | |
| 656 | /// } else { | |
| 657 | /// println!("everything's fine!"); | |
| 658 | /// } | |
| 659 | /// | |
| 660 | /// let greeting = if rude { | |
| 661 | /// "sup nerd." | |
| 662 | /// } else { | |
| 663 | /// "hello, friend!" | |
| 664 | /// }; | |
| 665 | /// | |
| 666 | /// if let Ok(x) = "123".parse::<i32>() { | |
| 667 | /// println!("{} double that and you get {}!", greeting, x * 2); | |
| 668 | /// } | |
| 669 | /// ``` | |
| 670 | /// | |
| 671 | /// Shown above are the three typical forms an `if` block comes in. First is the usual kind of | |
| 672 | /// thing you'd see in many languages, with an optional `else` block. Second uses `if` as an | |
| 673 | /// expression, which is only possible if all branches return the same type. An `if` expression can | |
| 674 | /// be used everywhere you'd expect. The third kind of `if` block is an `if let` block, which | |
| 675 | /// behaves similarly to using a `match` expression: | |
| 676 | /// | |
| 677 | /// ```rust | |
| 678 | /// if let Some(x) = Some(123) { | |
| 679 | /// // code | |
| 680 | /// # let _ = x; | |
| 681 | /// } else { | |
| 682 | /// // something else | |
| 683 | /// } | |
| 684 | /// | |
| 685 | /// match Some(123) { | |
| 686 | /// Some(x) => { | |
| 687 | /// // code | |
| 688 | /// # let _ = x; | |
| 689 | /// }, | |
| 690 | /// _ => { | |
| 691 | /// // something else | |
| 692 | /// }, | |
| 693 | /// } | |
| 694 | /// ``` | |
| 695 | /// | |
| 696 | /// Each kind of `if` expression can be mixed and matched as needed. | |
| 697 | /// | |
| 698 | /// ```rust | |
| 699 | /// if true == false { | |
| 700 | /// println!("oh no"); | |
| 701 | /// } else if "something" == "other thing" { | |
| 702 | /// println!("oh dear"); | |
| 703 | /// } else if let Some(200) = "blarg".parse::<i32>().ok() { | |
| 704 | /// println!("uh oh"); | |
| 705 | /// } else { | |
| 706 | /// println!("phew, nothing's broken"); | |
| 707 | /// } | |
| 708 | /// ``` | |
| 709 | /// | |
| 710 | /// The `if` keyword is used in one other place in Rust, namely as a part of pattern matching | |
| 711 | /// itself, allowing patterns such as `Some(x) if x > 200` to be used. | |
| 712 | /// | |
| 713 | /// For more information on `if` expressions, see the [Rust book] or the [Reference]. | |
| 714 | /// | |
| 715 | /// [Rust book]: ../book/ch03-05-control-flow.html#if-expressions | |
| 716 | /// [Reference]: ../reference/expressions/if-expr.html | |
| 717 | mod if_keyword {} | |
| 718 | ||
| 719 | #[doc(keyword = "impl")] | |
| 720 | // | |
| 721 | /// Implementations of functionality for a type, or a type implementing some functionality. | |
| 722 | /// | |
| 723 | /// There are two uses of the keyword `impl`: | |
| 724 | /// * An `impl` block is an item that is used to implement some functionality for a type. | |
| 725 | /// * An `impl Trait` in a type-position can be used to designate a type that implements a trait called `Trait`. | |
| 726 | /// | |
| 727 | /// # Implementing Functionality for a Type | |
| 728 | /// | |
| 729 | /// The `impl` keyword is primarily used to define implementations on types. Inherent | |
| 730 | /// implementations are standalone, while trait implementations are used to implement traits for | |
| 731 | /// types, or other traits. | |
| 732 | /// | |
| 733 | /// An implementation consists of definitions of functions and consts. A function defined in an | |
| 734 | /// `impl` block can be standalone, meaning it would be called like `Vec::new()`. If the function | |
| 735 | /// takes `self`, `&self`, or `&mut self` as its first argument, it can also be called using | |
| 736 | /// method-call syntax, a familiar feature to any object-oriented programmer, like `vec.len()`. | |
| 737 | /// | |
| 738 | /// ## Inherent Implementations | |
| 739 | /// | |
| 740 | /// ```rust | |
| 741 | /// struct Example { | |
| 742 | /// number: i32, | |
| 743 | /// } | |
| 744 | /// | |
| 745 | /// impl Example { | |
| 746 | /// fn boo() { | |
| 747 | /// println!("boo! Example::boo() was called!"); | |
| 748 | /// } | |
| 749 | /// | |
| 750 | /// fn answer(&mut self) { | |
| 751 | /// self.number += 42; | |
| 752 | /// } | |
| 753 | /// | |
| 754 | /// fn get_number(&self) -> i32 { | |
| 755 | /// self.number | |
| 756 | /// } | |
| 757 | /// } | |
| 758 | /// ``` | |
| 759 | /// | |
| 760 | /// It matters little where an inherent implementation is defined; | |
| 761 | /// its functionality is in scope wherever its implementing type is. | |
| 762 | /// | |
| 763 | /// ## Trait Implementations | |
| 764 | /// | |
| 765 | /// ```rust | |
| 766 | /// struct Example { | |
| 767 | /// number: i32, | |
| 768 | /// } | |
| 769 | /// | |
| 770 | /// trait Thingy { | |
| 771 | /// fn do_thingy(&self); | |
| 772 | /// } | |
| 773 | /// | |
| 774 | /// impl Thingy for Example { | |
| 775 | /// fn do_thingy(&self) { | |
| 776 | /// println!("doing a thing! also, number is {}!", self.number); | |
| 777 | /// } | |
| 778 | /// } | |
| 779 | /// ``` | |
| 780 | /// | |
| 781 | /// It matters little where a trait implementation is defined; | |
| 782 | /// its functionality can be brought into scope by importing the trait it implements. | |
| 783 | /// | |
| 784 | /// For more information on implementations, see the [Rust book][book1] or the [Reference]. | |
| 785 | /// | |
| 786 | /// # Designating a Type that Implements Some Functionality | |
| 787 | /// | |
| 788 | /// The other use of the `impl` keyword is in `impl Trait` syntax, which can be understood to mean | |
| 789 | /// "any (or some) concrete type that implements Trait". | |
| 790 | /// It can be used as the type of a variable declaration, | |
| 791 | /// in [argument position](https://rust-lang.github.io/rfcs/1951-expand-impl-trait.html) | |
| 792 | /// or in [return position](https://rust-lang.github.io/rfcs/3425-return-position-impl-trait-in-traits.html). | |
| 793 | /// One pertinent use case is in working with closures, which have unnameable types. | |
| 794 | /// | |
| 795 | /// ```rust | |
| 796 | /// fn thing_returning_closure() -> impl Fn(i32) -> bool { | |
| 797 | /// println!("here's a closure for you!"); | |
| 798 | /// |x: i32| x % 3 == 0 | |
| 799 | /// } | |
| 800 | /// ``` | |
| 801 | /// | |
| 802 | /// For more information on `impl Trait` syntax, see the [Rust book][book2]. | |
| 803 | /// | |
| 804 | /// [book1]: ../book/ch05-03-method-syntax.html | |
| 805 | /// [Reference]: ../reference/items/implementations.html | |
| 806 | /// [book2]: ../book/ch10-02-traits.html#returning-types-that-implement-traits | |
| 807 | mod impl_keyword {} | |
| 808 | ||
| 809 | #[doc(keyword = "in")] | |
| 810 | // | |
| 811 | /// Iterate over a series of values with [`for`]. | |
| 812 | /// | |
| 813 | /// The expression immediately following `in` must implement the [`IntoIterator`] trait. | |
| 814 | /// | |
| 815 | /// ## Literal Examples: | |
| 816 | /// | |
| 817 | /// * `for _ in 1..3 {}` - Iterate over an exclusive range up to but excluding 3. | |
| 818 | /// * `for _ in 1..=3 {}` - Iterate over an inclusive range up to and including 3. | |
| 819 | /// | |
| 820 | /// (Read more about [range patterns]) | |
| 821 | /// | |
| 822 | /// [`IntoIterator`]: ../book/ch13-04-performance.html | |
| 823 | /// [range patterns]: ../reference/patterns.html?highlight=range#range-patterns | |
| 824 | /// [`for`]: keyword.for.html | |
| 825 | /// | |
| 826 | /// The other use of `in` is with the keyword `pub`. It allows users to declare an item as visible | |
| 827 | /// only within a given scope. | |
| 828 | /// | |
| 829 | /// ## Literal Example: | |
| 830 | /// | |
| 831 | /// * `pub(in crate::outer_mod) fn outer_mod_visible_fn() {}` - fn is visible in `outer_mod` | |
| 832 | /// | |
| 833 | /// Starting with the 2018 edition, paths for `pub(in path)` must start with `crate`, `self` or | |
| 834 | /// `super`. The 2015 edition may also use paths starting with `::` or modules from the crate root. | |
| 835 | /// | |
| 836 | /// For more information, see the [Reference]. | |
| 837 | /// | |
| 838 | /// [Reference]: ../reference/visibility-and-privacy.html#pubin-path-pubcrate-pubsuper-and-pubself | |
| 839 | mod in_keyword {} | |
| 840 | ||
| 841 | #[doc(keyword = "let")] | |
| 842 | // | |
| 843 | /// Bind a value to a variable. | |
| 844 | /// | |
| 845 | /// The primary use for the `let` keyword is in `let` statements, which are used to introduce a new | |
| 846 | /// set of variables into the current scope, as given by a pattern. | |
| 847 | /// | |
| 848 | /// ```rust | |
| 849 | /// # #![allow(unused_assignments)] | |
| 850 | /// let thing1: i32 = 100; | |
| 851 | /// let thing2 = 200 + thing1; | |
| 852 | /// | |
| 853 | /// let mut changing_thing = true; | |
| 854 | /// changing_thing = false; | |
| 855 | /// | |
| 856 | /// let (part1, part2) = ("first", "second"); | |
| 857 | /// | |
| 858 | /// struct Example { | |
| 859 | /// a: bool, | |
| 860 | /// b: u64, | |
| 861 | /// } | |
| 862 | /// | |
| 863 | /// let Example { a, b: _ } = Example { | |
| 864 | /// a: true, | |
| 865 | /// b: 10004, | |
| 866 | /// }; | |
| 867 | /// assert!(a); | |
| 868 | /// ``` | |
| 869 | /// | |
| 870 | /// The pattern is most commonly a single variable, which means no pattern matching is done and | |
| 871 | /// the expression given is bound to the variable. Apart from that, patterns used in `let` bindings | |
| 872 | /// can be as complicated as needed, given that the pattern is exhaustive. See the [Rust | |
| 873 | /// book][book1] for more information on pattern matching. The type of the pattern is optionally | |
| 874 | /// given afterwards, but if left blank is automatically inferred by the compiler if possible. | |
| 875 | /// | |
| 876 | /// Variables in Rust are immutable by default, and require the `mut` keyword to be made mutable. | |
| 877 | /// | |
| 878 | /// Multiple variables can be defined with the same name, known as shadowing. This doesn't affect | |
| 879 | /// the original variable in any way beyond being unable to directly access it beyond the point of | |
| 880 | /// shadowing. It continues to remain in scope, getting dropped only when it falls out of scope. | |
| 881 | /// Shadowed variables don't need to have the same type as the variables shadowing them. | |
| 882 | /// | |
| 883 | /// ```rust | |
| 884 | /// let shadowing_example = true; | |
| 885 | /// let shadowing_example = 123.4; | |
| 886 | /// let shadowing_example = shadowing_example as u32; | |
| 887 | /// let mut shadowing_example = format!("cool! {shadowing_example}"); | |
| 888 | /// shadowing_example += " something else!"; // not shadowing | |
| 889 | /// ``` | |
| 890 | /// | |
| 891 | /// Other places the `let` keyword is used include along with [`if`], in the form of `if let` | |
| 892 | /// expressions. They're useful if the pattern being matched isn't exhaustive, such as with | |
| 893 | /// enumerations. `while let` also exists, which runs a loop with a pattern matched value until | |
| 894 | /// that pattern can't be matched. | |
| 895 | /// | |
| 896 | /// For more information on the `let` keyword, see the [Rust book][book2] or the [Reference] | |
| 897 | /// | |
| 898 | /// [book1]: ../book/ch06-02-match.html | |
| 899 | /// [`if`]: keyword.if.html | |
| 900 | /// [book2]: ../book/ch18-01-all-the-places-for-patterns.html#let-statements | |
| 901 | /// [Reference]: ../reference/statements.html#let-statements | |
| 902 | mod let_keyword {} | |
| 903 | ||
| 904 | #[doc(keyword = "loop")] | |
| 905 | // | |
| 906 | /// Loop indefinitely. | |
| 907 | /// | |
| 908 | /// `loop` is used to define the simplest kind of loop supported in Rust. It runs the code inside | |
| 909 | /// it until the code uses `break` or the program exits. | |
| 910 | /// | |
| 911 | /// ```rust | |
| 912 | /// loop { | |
| 913 | /// println!("hello world forever!"); | |
| 914 | /// # break; | |
| 915 | /// } | |
| 916 | /// | |
| 917 | /// let mut i = 1; | |
| 918 | /// loop { | |
| 919 | /// println!("i is {i}"); | |
| 920 | /// if i > 100 { | |
| 921 | /// break; | |
| 922 | /// } | |
| 923 | /// i *= 2; | |
| 924 | /// } | |
| 925 | /// assert_eq!(i, 128); | |
| 926 | /// ``` | |
| 927 | /// | |
| 928 | /// Unlike the other kinds of loops in Rust (`while`, `while let`, and `for`), loops can be used as | |
| 929 | /// expressions that return values via `break`. | |
| 930 | /// | |
| 931 | /// ```rust | |
| 932 | /// let mut i = 1; | |
| 933 | /// let something = loop { | |
| 934 | /// i *= 2; | |
| 935 | /// if i > 100 { | |
| 936 | /// break i; | |
| 937 | /// } | |
| 938 | /// }; | |
| 939 | /// assert_eq!(something, 128); | |
| 940 | /// ``` | |
| 941 | /// | |
| 942 | /// Every `break` in a loop has to have the same type. When it's not explicitly giving something, | |
| 943 | /// `break;` returns `()`. | |
| 944 | /// | |
| 945 | /// For more information on `loop` and loops in general, see the [Reference]. | |
| 946 | /// | |
| 947 | /// See also, [`for`], [`while`]. | |
| 948 | /// | |
| 949 | /// [`for`]: keyword.for.html | |
| 950 | /// [`while`]: keyword.while.html | |
| 951 | /// [Reference]: ../reference/expressions/loop-expr.html | |
| 952 | mod loop_keyword {} | |
| 953 | ||
| 954 | #[doc(keyword = "match")] | |
| 955 | // | |
| 956 | /// Control flow based on pattern matching. | |
| 957 | /// | |
| 958 | /// `match` can be used to run code conditionally. Every pattern must | |
| 959 | /// be handled exhaustively either explicitly or by using wildcards like | |
| 960 | /// `_` in the `match`. Since `match` is an expression, values can also be | |
| 961 | /// returned. | |
| 962 | /// | |
| 963 | /// ```rust | |
| 964 | /// let opt: Option<usize> = None; | |
| 965 | /// let x = match opt { | |
| 966 | /// Some(int) => int, | |
| 967 | /// None => 10, | |
| 968 | /// }; | |
| 969 | /// assert_eq!(x, 10); | |
| 970 | /// | |
| 971 | /// let a_number = Some(10); | |
| 972 | /// match a_number { | |
| 973 | /// Some(x) if x <= 5 => println!("0 to 5 num = {x}"), | |
| 974 | /// Some(x @ 6..=10) => println!("6 to 10 num = {x}"), | |
| 975 | /// None => panic!(), | |
| 976 | /// // all other numbers | |
| 977 | /// _ => panic!(), | |
| 978 | /// } | |
| 979 | /// ``` | |
| 980 | /// | |
| 981 | /// `match` can be used to gain access to the inner members of an enum | |
| 982 | /// and use them directly. | |
| 983 | /// | |
| 984 | /// ```rust | |
| 985 | /// enum Outer { | |
| 986 | /// Double(Option<u8>, Option<String>), | |
| 987 | /// Single(Option<u8>), | |
| 988 | /// Empty | |
| 989 | /// } | |
| 990 | /// | |
| 991 | /// let get_inner = Outer::Double(None, Some(String::new())); | |
| 992 | /// match get_inner { | |
| 993 | /// Outer::Double(None, Some(st)) => println!("{st}"), | |
| 994 | /// Outer::Single(opt) => println!("{opt:?}"), | |
| 995 | /// _ => panic!(), | |
| 996 | /// } | |
| 997 | /// ``` | |
| 998 | /// | |
| 999 | /// For more information on `match` and matching in general, see the [Reference]. | |
| 1000 | /// | |
| 1001 | /// [Reference]: ../reference/expressions/match-expr.html | |
| 1002 | mod match_keyword {} | |
| 1003 | ||
| 1004 | #[doc(keyword = "mod")] | |
| 1005 | // | |
| 1006 | /// Organize code into [modules]. | |
| 1007 | /// | |
| 1008 | /// Use `mod` to create new [modules] to encapsulate code, including other | |
| 1009 | /// modules: | |
| 1010 | /// | |
| 1011 | /// ``` | |
| 1012 | /// mod foo { | |
| 1013 | /// mod bar { | |
| 1014 | /// type MyType = (u8, u8); | |
| 1015 | /// fn baz() {} | |
| 1016 | /// } | |
| 1017 | /// } | |
| 1018 | /// ``` | |
| 1019 | /// | |
| 1020 | /// Like [`struct`]s and [`enum`]s, a module and its content are private by | |
| 1021 | /// default, inaccessible to code outside of the module. | |
| 1022 | /// | |
| 1023 | /// To learn more about allowing access, see the documentation for the [`pub`] | |
| 1024 | /// keyword. | |
| 1025 | /// | |
| 1026 | /// [`enum`]: keyword.enum.html | |
| 1027 | /// [`pub`]: keyword.pub.html | |
| 1028 | /// [`struct`]: keyword.struct.html | |
| 1029 | /// [modules]: ../reference/items/modules.html | |
| 1030 | mod mod_keyword {} | |
| 1031 | ||
| 1032 | #[doc(keyword = "move")] | |
| 1033 | // | |
| 1034 | /// Capture a [closure]'s environment by value. | |
| 1035 | /// | |
| 1036 | /// `move` converts any variables captured by reference or mutable reference | |
| 1037 | /// to variables captured by value. | |
| 1038 | /// | |
| 1039 | /// ```rust | |
| 1040 | /// let data = vec![1, 2, 3]; | |
| 1041 | /// let closure = move || println!("captured {data:?} by value"); | |
| 1042 | /// | |
| 1043 | /// // data is no longer available, it is owned by the closure | |
| 1044 | /// ``` | |
| 1045 | /// | |
| 1046 | /// Note: `move` closures may still implement [`Fn`] or [`FnMut`], even though | |
| 1047 | /// they capture variables by `move`. This is because the traits implemented by | |
| 1048 | /// a closure type are determined by *what* the closure does with captured | |
| 1049 | /// values, not *how* it captures them: | |
| 1050 | /// | |
| 1051 | /// ```rust | |
| 1052 | /// fn create_fn() -> impl Fn() { | |
| 1053 | /// let text = "Fn".to_owned(); | |
| 1054 | /// move || println!("This is a: {text}") | |
| 1055 | /// } | |
| 1056 | /// | |
| 1057 | /// let fn_plain = create_fn(); | |
| 1058 | /// fn_plain(); | |
| 1059 | /// ``` | |
| 1060 | /// | |
| 1061 | /// `move` is often used when [threads] are involved. | |
| 1062 | /// | |
| 1063 | /// ```rust | |
| 1064 | /// let data = vec![1, 2, 3]; | |
| 1065 | /// | |
| 1066 | /// std::thread::spawn(move || { | |
| 1067 | /// println!("captured {data:?} by value") | |
| 1068 | /// }).join().unwrap(); | |
| 1069 | /// | |
| 1070 | /// // data was moved to the spawned thread, so we cannot use it here | |
| 1071 | /// ``` | |
| 1072 | /// | |
| 1073 | /// `move` is also valid before an async block. | |
| 1074 | /// | |
| 1075 | /// ```rust | |
| 1076 | /// let capture = "hello".to_owned(); | |
| 1077 | /// let block = async move { | |
| 1078 | /// println!("rust says {capture} from async block"); | |
| 1079 | /// }; | |
| 1080 | /// ``` | |
| 1081 | /// | |
| 1082 | /// For more information on the `move` keyword, see the [closures][closure] section | |
| 1083 | /// of the Rust book or the [threads] section. | |
| 1084 | /// | |
| 1085 | /// [closure]: ../book/ch13-01-closures.html | |
| 1086 | /// [threads]: ../book/ch16-01-threads.html#using-move-closures-with-threads | |
| 1087 | mod move_keyword {} | |
| 1088 | ||
| 1089 | #[doc(keyword = "mut")] | |
| 1090 | // | |
| 1091 | /// A mutable variable, reference, or pointer. | |
| 1092 | /// | |
| 1093 | /// `mut` can be used in several situations. The first is mutable variables, | |
| 1094 | /// which can be used anywhere you can bind a value to a variable name. Some | |
| 1095 | /// examples: | |
| 1096 | /// | |
| 1097 | /// ```rust | |
| 1098 | /// // A mutable variable in the parameter list of a function. | |
| 1099 | /// fn foo(mut x: u8, y: u8) -> u8 { | |
| 1100 | /// x += y; | |
| 1101 | /// x | |
| 1102 | /// } | |
| 1103 | /// | |
| 1104 | /// // Modifying a mutable variable. | |
| 1105 | /// # #[allow(unused_assignments)] | |
| 1106 | /// let mut a = 5; | |
| 1107 | /// a = 6; | |
| 1108 | /// | |
| 1109 | /// assert_eq!(foo(3, 4), 7); | |
| 1110 | /// assert_eq!(a, 6); | |
| 1111 | /// ``` | |
| 1112 | /// | |
| 1113 | /// The second is mutable references. They can be created from `mut` variables | |
| 1114 | /// and must be unique: no other variables can have a mutable reference, nor a | |
| 1115 | /// shared reference. | |
| 1116 | /// | |
| 1117 | /// ```rust | |
| 1118 | /// // Taking a mutable reference. | |
| 1119 | /// fn push_two(v: &mut Vec<u8>) { | |
| 1120 | /// v.push(2); | |
| 1121 | /// } | |
| 1122 | /// | |
| 1123 | /// // A mutable reference cannot be taken to a non-mutable variable. | |
| 1124 | /// let mut v = vec![0, 1]; | |
| 1125 | /// // Passing a mutable reference. | |
| 1126 | /// push_two(&mut v); | |
| 1127 | /// | |
| 1128 | /// assert_eq!(v, vec![0, 1, 2]); | |
| 1129 | /// ``` | |
| 1130 | /// | |
| 1131 | /// ```rust,compile_fail,E0502 | |
| 1132 | /// let mut v = vec![0, 1]; | |
| 1133 | /// let mut_ref_v = &mut v; | |
| 1134 | /// # #[allow(unused)] | |
| 1135 | /// let ref_v = &v; | |
| 1136 | /// mut_ref_v.push(2); | |
| 1137 | /// ``` | |
| 1138 | /// | |
| 1139 | /// Mutable raw pointers work much like mutable references, with the added | |
| 1140 | /// possibility of not pointing to a valid object. The syntax is `*mut Type`. | |
| 1141 | /// | |
| 1142 | /// More information on mutable references and pointers can be found in the [Reference]. | |
| 1143 | /// | |
| 1144 | /// [Reference]: ../reference/types/pointer.html#mutable-references-mut | |
| 1145 | mod mut_keyword {} | |
| 1146 | ||
| 1147 | #[doc(keyword = "pub")] | |
| 1148 | // | |
| 1149 | /// Make an item visible to others. | |
| 1150 | /// | |
| 1151 | /// The keyword `pub` makes any module, function, or data structure accessible from inside | |
| 1152 | /// of external modules. The `pub` keyword may also be used in a `use` declaration to re-export | |
| 1153 | /// an identifier from a namespace. | |
| 1154 | /// | |
| 1155 | /// For more information on the `pub` keyword, please see the visibility section | |
| 1156 | /// of the [reference] and for some examples, see [Rust by Example]. | |
| 1157 | /// | |
| 1158 | /// [reference]:../reference/visibility-and-privacy.html?highlight=pub#visibility-and-privacy | |
| 1159 | /// [Rust by Example]:../rust-by-example/mod/visibility.html | |
| 1160 | mod pub_keyword {} | |
| 1161 | ||
| 1162 | #[doc(keyword = "ref")] | |
| 1163 | // | |
| 1164 | /// Bind by reference during pattern matching. | |
| 1165 | /// | |
| 1166 | /// `ref` annotates pattern bindings to make them borrow rather than move. | |
| 1167 | /// It is **not** a part of the pattern as far as matching is concerned: it does | |
| 1168 | /// not affect *whether* a value is matched, only *how* it is matched. | |
| 1169 | /// | |
| 1170 | /// By default, [`match`] statements consume all they can, which can sometimes | |
| 1171 | /// be a problem, when you don't really need the value to be moved and owned: | |
| 1172 | /// | |
| 1173 | /// ```compile_fail,E0382 | |
| 1174 | /// let maybe_name = Some(String::from("Alice")); | |
| 1175 | /// // The variable 'maybe_name' is consumed here ... | |
| 1176 | /// match maybe_name { | |
| 1177 | /// Some(n) => println!("Hello, {n}"), | |
| 1178 | /// _ => println!("Hello, world"), | |
| 1179 | /// } | |
| 1180 | /// // ... and is now unavailable. | |
| 1181 | /// println!("Hello again, {}", maybe_name.unwrap_or("world".into())); | |
| 1182 | /// ``` | |
| 1183 | /// | |
| 1184 | /// Using the `ref` keyword, the value is only borrowed, not moved, making it | |
| 1185 | /// available for use after the [`match`] statement: | |
| 1186 | /// | |
| 1187 | /// ``` | |
| 1188 | /// let maybe_name = Some(String::from("Alice")); | |
| 1189 | /// // Using `ref`, the value is borrowed, not moved ... | |
| 1190 | /// match maybe_name { | |
| 1191 | /// Some(ref n) => println!("Hello, {n}"), | |
| 1192 | /// _ => println!("Hello, world"), | |
| 1193 | /// } | |
| 1194 | /// // ... so it's available here! | |
| 1195 | /// println!("Hello again, {}", maybe_name.unwrap_or("world".into())); | |
| 1196 | /// ``` | |
| 1197 | /// | |
| 1198 | /// # `&` vs `ref` | |
| 1199 | /// | |
| 1200 | /// - `&` denotes that your pattern expects a reference to an object. Hence `&` | |
| 1201 | /// is a part of said pattern: `&Foo` matches different objects than `Foo` does. | |
| 1202 | /// | |
| 1203 | /// - `ref` indicates that you want a reference to an unpacked value. It is not | |
| 1204 | /// matched against: `Foo(ref foo)` matches the same objects as `Foo(foo)`. | |
| 1205 | /// | |
| 1206 | /// See also the [Reference] for more information. | |
| 1207 | /// | |
| 1208 | /// [`match`]: keyword.match.html | |
| 1209 | /// [Reference]: ../reference/patterns.html#identifier-patterns | |
| 1210 | mod ref_keyword {} | |
| 1211 | ||
| 1212 | #[doc(keyword = "return")] | |
| 1213 | // | |
| 1214 | /// Returns a value from a function. | |
| 1215 | /// | |
| 1216 | /// A `return` marks the end of an execution path in a function: | |
| 1217 | /// | |
| 1218 | /// ``` | |
| 1219 | /// fn foo() -> i32 { | |
| 1220 | /// return 3; | |
| 1221 | /// } | |
| 1222 | /// assert_eq!(foo(), 3); | |
| 1223 | /// ``` | |
| 1224 | /// | |
| 1225 | /// `return` is not needed when the returned value is the last expression in the | |
| 1226 | /// function. In this case the `;` is omitted: | |
| 1227 | /// | |
| 1228 | /// ``` | |
| 1229 | /// fn foo() -> i32 { | |
| 1230 | /// 3 | |
| 1231 | /// } | |
| 1232 | /// assert_eq!(foo(), 3); | |
| 1233 | /// ``` | |
| 1234 | /// | |
| 1235 | /// `return` returns from the function immediately (an "early return"): | |
| 1236 | /// | |
| 1237 | /// ```no_run | |
| 1238 | /// use std::fs::File; | |
| 1239 | /// use std::io::{Error, ErrorKind, Read, Result}; | |
| 1240 | /// | |
| 1241 | /// fn main() -> Result<()> { | |
| 1242 | /// let mut file = match File::open("foo.txt") { | |
| 1243 | /// Ok(f) => f, | |
| 1244 | /// Err(e) => return Err(e), | |
| 1245 | /// }; | |
| 1246 | /// | |
| 1247 | /// let mut contents = String::new(); | |
| 1248 | /// let size = match file.read_to_string(&mut contents) { | |
| 1249 | /// Ok(s) => s, | |
| 1250 | /// Err(e) => return Err(e), | |
| 1251 | /// }; | |
| 1252 | /// | |
| 1253 | /// if contents.contains("impossible!") { | |
| 1254 | /// return Err(Error::new(ErrorKind::Other, "oh no!")); | |
| 1255 | /// } | |
| 1256 | /// | |
| 1257 | /// if size > 9000 { | |
| 1258 | /// return Err(Error::new(ErrorKind::Other, "over 9000!")); | |
| 1259 | /// } | |
| 1260 | /// | |
| 1261 | /// assert_eq!(contents, "Hello, world!"); | |
| 1262 | /// Ok(()) | |
| 1263 | /// } | |
| 1264 | /// ``` | |
| 1265 | /// | |
| 1266 | /// Within [closures] and [`async`] blocks, `return` returns a value from within the closure or | |
| 1267 | /// `async` block, not from the parent function: | |
| 1268 | /// | |
| 1269 | /// ```rust | |
| 1270 | /// fn foo() -> i32 { | |
| 1271 | /// let closure = || { | |
| 1272 | /// return 5; | |
| 1273 | /// }; | |
| 1274 | /// | |
| 1275 | /// let future = async { | |
| 1276 | /// return 10; | |
| 1277 | /// }; | |
| 1278 | /// | |
| 1279 | /// return 15; | |
| 1280 | /// } | |
| 1281 | /// | |
| 1282 | /// assert_eq!(foo(), 15); | |
| 1283 | /// ``` | |
| 1284 | /// | |
| 1285 | /// [closures]: ../book/ch13-01-closures.html | |
| 1286 | /// [`async`]: ../std/keyword.async.html | |
| 1287 | mod return_keyword {} | |
| 1288 | ||
| 1289 | #[doc(keyword = "become")] | |
| 1290 | // | |
| 1291 | /// Perform a tail-call of a function. | |
| 1292 | /// | |
| 1293 | /// <div class="warning"> | |
| 1294 | /// | |
| 1295 | /// `feature(explicit_tail_calls)` is currently incomplete and may not work properly. | |
| 1296 | /// </div> | |
| 1297 | /// | |
| 1298 | /// When tail calling a function, instead of its stack frame being added to the | |
| 1299 | /// stack, the stack frame of the caller is directly replaced with the callee's. | |
| 1300 | /// This means that as long as a loop in a call graph only uses tail calls, the | |
| 1301 | /// stack growth will be bounded. | |
| 1302 | /// | |
| 1303 | /// This is useful for writing functional-style code (since it prevents recursion | |
| 1304 | /// from exhausting resources) or for code optimization (since a tail call | |
| 1305 | /// *might* be cheaper than a normal call, tail calls can be used in a similar | |
| 1306 | /// manner to computed goto). | |
| 1307 | /// | |
| 1308 | /// Example of using `become` to implement functional-style `fold`: | |
| 1309 | /// ``` | |
| 1310 | /// #![feature(explicit_tail_calls)] | |
| 1311 | /// #![expect(incomplete_features)] | |
| 1312 | /// | |
| 1313 | /// fn fold<T: Copy, S>(slice: &[T], init: S, f: impl Fn(S, T) -> S) -> S { | |
| 1314 | /// match slice { | |
| 1315 | /// // without `become`, on big inputs this could easily overflow the | |
| 1316 | /// // stack. using a tail call guarantees that the stack will not grow unboundedly | |
| 1317 | /// [first, rest @ ..] => become fold(rest, f(init, *first), f), | |
| 1318 | /// [] => init, | |
| 1319 | /// } | |
| 1320 | /// } | |
| 1321 | /// ``` | |
| 1322 | /// | |
| 1323 | /// Compilers can already perform "tail call optimization" -- they can replace normal | |
| 1324 | /// calls with tail calls, although there are no guarantees that this will be done. | |
| 1325 | /// However, to perform TCO, the call needs to be the last thing that happens | |
| 1326 | /// in the functions and be returned from it. This requirement is often broken | |
| 1327 | /// by drop code for locals, which is run after computing the return expression: | |
| 1328 | /// | |
| 1329 | /// ``` | |
| 1330 | /// fn example() { | |
| 1331 | /// let string = "meow".to_owned(); | |
| 1332 | /// println!("{string}"); | |
| 1333 | /// return help(); // this is *not* the last thing that happens in `example`... | |
| 1334 | /// } | |
| 1335 | /// | |
| 1336 | /// // ... because it is desugared to this: | |
| 1337 | /// fn example_desugared() { | |
| 1338 | /// let string = "meow".to_owned(); | |
| 1339 | /// println!("{string}"); | |
| 1340 | /// let tmp = help(); | |
| 1341 | /// drop(string); | |
| 1342 | /// return tmp; | |
| 1343 | /// } | |
| 1344 | /// | |
| 1345 | /// fn help() {} | |
| 1346 | /// ``` | |
| 1347 | /// | |
| 1348 | /// For this reason, `become` also changes the drop order, such that locals are | |
| 1349 | /// dropped *before* evaluating the call. | |
| 1350 | /// | |
| 1351 | /// In order to guarantee that the compiler can perform a tail call, `become` | |
| 1352 | /// currently has these requirements: | |
| 1353 | /// 1. callee and caller must have the same ABI, arguments, and return type | |
| 1354 | /// 2. callee and caller must not have varargs | |
| 1355 | /// 3. caller must not be marked with `#[track_caller]` | |
| 1356 | /// - callee is allowed to be marked with `#[track_caller]` as otherwise | |
| 1357 | /// adding `#[track_caller]` would be a breaking change. if callee is | |
| 1358 | /// marked with `#[track_caller]` a tail call is not guaranteed. | |
| 1359 | /// 4. callee and caller cannot be a closure | |
| 1360 | /// (unless it's coerced to a function pointer) | |
| 1361 | /// | |
| 1362 | /// It is possible to tail-call a function pointer: | |
| 1363 | /// ``` | |
| 1364 | /// #![feature(explicit_tail_calls)] | |
| 1365 | /// #![expect(incomplete_features)] | |
| 1366 | /// | |
| 1367 | /// #[derive(Copy, Clone)] | |
| 1368 | /// enum Inst { Inc, Dec } | |
| 1369 | /// | |
| 1370 | /// fn dispatch(stream: &[Inst], state: u32) -> u32 { | |
| 1371 | /// const TABLE: &[fn(&[Inst], u32) -> u32] = &[increment, decrement]; | |
| 1372 | /// match stream { | |
| 1373 | /// [inst, rest @ ..] => become TABLE[*inst as usize](rest, state), | |
| 1374 | /// [] => state, | |
| 1375 | /// } | |
| 1376 | /// } | |
| 1377 | /// | |
| 1378 | /// fn increment(stream: &[Inst], state: u32) -> u32 { | |
| 1379 | /// become dispatch(stream, state + 1) | |
| 1380 | /// } | |
| 1381 | /// | |
| 1382 | /// fn decrement(stream: &[Inst], state: u32) -> u32 { | |
| 1383 | /// become dispatch(stream, state - 1) | |
| 1384 | /// } | |
| 1385 | /// | |
| 1386 | /// let program = &[Inst::Inc, Inst::Inc, Inst::Dec, Inst::Inc]; | |
| 1387 | /// assert_eq!(dispatch(program, 0), 2); | |
| 1388 | /// ``` | |
| 1389 | mod become_keyword {} | |
| 1390 | ||
| 1391 | #[doc(keyword = "self")] | |
| 1392 | // | |
| 1393 | /// The receiver of a method, or the current module. | |
| 1394 | /// | |
| 1395 | /// `self` is used in two situations: referencing the current module and marking | |
| 1396 | /// the receiver of a method. | |
| 1397 | /// | |
| 1398 | /// In paths, `self` can be used to refer to the current module, either in a | |
| 1399 | /// [`use`] statement or in a path to access an element: | |
| 1400 | /// | |
| 1401 | /// ``` | |
| 1402 | /// # #![allow(unused_imports)] | |
| 1403 | /// use std::io::{self, Read}; | |
| 1404 | /// ``` | |
| 1405 | /// | |
| 1406 | /// Is functionally the same as: | |
| 1407 | /// | |
| 1408 | /// ``` | |
| 1409 | /// # #![allow(unused_imports)] | |
| 1410 | /// use std::io; | |
| 1411 | /// use std::io::Read; | |
| 1412 | /// ``` | |
| 1413 | /// | |
| 1414 | /// Using `self` to access an element in the current module: | |
| 1415 | /// | |
| 1416 | /// ``` | |
| 1417 | /// # #![allow(dead_code)] | |
| 1418 | /// # fn main() {} | |
| 1419 | /// fn foo() {} | |
| 1420 | /// fn bar() { | |
| 1421 | /// self::foo() | |
| 1422 | /// } | |
| 1423 | /// ``` | |
| 1424 | /// | |
| 1425 | /// `self` as the current receiver for a method allows to omit the parameter | |
| 1426 | /// type most of the time. With the exception of this particularity, `self` is | |
| 1427 | /// used much like any other parameter: | |
| 1428 | /// | |
| 1429 | /// ``` | |
| 1430 | /// struct Foo(i32); | |
| 1431 | /// | |
| 1432 | /// impl Foo { | |
| 1433 | /// // No `self`. | |
| 1434 | /// fn new() -> Self { | |
| 1435 | /// Self(0) | |
| 1436 | /// } | |
| 1437 | /// | |
| 1438 | /// // Consuming `self`. | |
| 1439 | /// fn consume(self) -> Self { | |
| 1440 | /// Self(self.0 + 1) | |
| 1441 | /// } | |
| 1442 | /// | |
| 1443 | /// // Borrowing `self`. | |
| 1444 | /// fn borrow(&self) -> &i32 { | |
| 1445 | /// &self.0 | |
| 1446 | /// } | |
| 1447 | /// | |
| 1448 | /// // Borrowing `self` mutably. | |
| 1449 | /// fn borrow_mut(&mut self) -> &mut i32 { | |
| 1450 | /// &mut self.0 | |
| 1451 | /// } | |
| 1452 | /// } | |
| 1453 | /// | |
| 1454 | /// // This method must be called with a `Type::` prefix. | |
| 1455 | /// let foo = Foo::new(); | |
| 1456 | /// assert_eq!(foo.0, 0); | |
| 1457 | /// | |
| 1458 | /// // Those two calls produces the same result. | |
| 1459 | /// let foo = Foo::consume(foo); | |
| 1460 | /// assert_eq!(foo.0, 1); | |
| 1461 | /// let foo = foo.consume(); | |
| 1462 | /// assert_eq!(foo.0, 2); | |
| 1463 | /// | |
| 1464 | /// // Borrowing is handled automatically with the second syntax. | |
| 1465 | /// let borrow_1 = Foo::borrow(&foo); | |
| 1466 | /// let borrow_2 = foo.borrow(); | |
| 1467 | /// assert_eq!(borrow_1, borrow_2); | |
| 1468 | /// | |
| 1469 | /// // Borrowing mutably is handled automatically too with the second syntax. | |
| 1470 | /// let mut foo = Foo::new(); | |
| 1471 | /// *Foo::borrow_mut(&mut foo) += 1; | |
| 1472 | /// assert_eq!(foo.0, 1); | |
| 1473 | /// *foo.borrow_mut() += 1; | |
| 1474 | /// assert_eq!(foo.0, 2); | |
| 1475 | /// ``` | |
| 1476 | /// | |
| 1477 | /// Note that this automatic conversion when calling `foo.method()` is not | |
| 1478 | /// limited to the examples above. See the [Reference] for more information. | |
| 1479 | /// | |
| 1480 | /// [`use`]: keyword.use.html | |
| 1481 | /// [Reference]: ../reference/items/associated-items.html#methods | |
| 1482 | mod self_keyword {} | |
| 1483 | ||
| 1484 | // FIXME: Once rustdoc can handle URL conflicts on case insensitive file systems, we can replace | |
| 1485 | // these two lines with `#[doc(keyword = "Self")]` and update `is_doc_keyword` in | |
| 1486 | // `CheckAttrVisitor`. | |
| 1487 | #[doc(alias = "Self")] | |
| 1488 | #[doc(keyword = "SelfTy")] | |
| 1489 | // | |
| 1490 | /// The implementing type within a [`trait`] or [`impl`] block, or the current type within a type | |
| 1491 | /// definition. | |
| 1492 | /// | |
| 1493 | /// Within a type definition: | |
| 1494 | /// | |
| 1495 | /// ``` | |
| 1496 | /// # #![allow(dead_code)] | |
| 1497 | /// struct Node { | |
| 1498 | /// elem: i32, | |
| 1499 | /// // `Self` is a `Node` here. | |
| 1500 | /// next: Option<Box<Self>>, | |
| 1501 | /// } | |
| 1502 | /// ``` | |
| 1503 | /// | |
| 1504 | /// In an [`impl`] block: | |
| 1505 | /// | |
| 1506 | /// ``` | |
| 1507 | /// struct Foo(i32); | |
| 1508 | /// | |
| 1509 | /// impl Foo { | |
| 1510 | /// fn new() -> Self { | |
| 1511 | /// Self(0) | |
| 1512 | /// } | |
| 1513 | /// } | |
| 1514 | /// | |
| 1515 | /// assert_eq!(Foo::new().0, Foo(0).0); | |
| 1516 | /// ``` | |
| 1517 | /// | |
| 1518 | /// Generic parameters are implicit with `Self`: | |
| 1519 | /// | |
| 1520 | /// ``` | |
| 1521 | /// # #![allow(dead_code)] | |
| 1522 | /// struct Wrap<T> { | |
| 1523 | /// elem: T, | |
| 1524 | /// } | |
| 1525 | /// | |
| 1526 | /// impl<T> Wrap<T> { | |
| 1527 | /// fn new(elem: T) -> Self { | |
| 1528 | /// Self { elem } | |
| 1529 | /// } | |
| 1530 | /// } | |
| 1531 | /// ``` | |
| 1532 | /// | |
| 1533 | /// In a [`trait`] definition and related [`impl`] block: | |
| 1534 | /// | |
| 1535 | /// ``` | |
| 1536 | /// trait Example { | |
| 1537 | /// fn example() -> Self; | |
| 1538 | /// } | |
| 1539 | /// | |
| 1540 | /// struct Foo(i32); | |
| 1541 | /// | |
| 1542 | /// impl Example for Foo { | |
| 1543 | /// fn example() -> Self { | |
| 1544 | /// Self(42) | |
| 1545 | /// } | |
| 1546 | /// } | |
| 1547 | /// | |
| 1548 | /// assert_eq!(Foo::example().0, Foo(42).0); | |
| 1549 | /// ``` | |
| 1550 | /// | |
| 1551 | /// [`impl`]: keyword.impl.html | |
| 1552 | /// [`trait`]: keyword.trait.html | |
| 1553 | mod self_upper_keyword {} | |
| 1554 | ||
| 1555 | #[doc(keyword = "static")] | |
| 1556 | // | |
| 1557 | /// A static item is a value which is valid for the entire duration of your | |
| 1558 | /// program (a `'static` lifetime). | |
| 1559 | /// | |
| 1560 | /// On the surface, `static` items seem very similar to [`const`]s: both contain | |
| 1561 | /// a value, both require type annotations and both can only be initialized with | |
| 1562 | /// constant functions and values. However, `static`s are notably different in | |
| 1563 | /// that they represent a location in memory. That means that you can have | |
| 1564 | /// references to `static` items and potentially even modify them, making them | |
| 1565 | /// essentially global variables. | |
| 1566 | /// | |
| 1567 | /// Static items do not call [`drop`] at the end of the program. | |
| 1568 | /// | |
| 1569 | /// There are two types of `static` items: those declared in association with | |
| 1570 | /// the [`mut`] keyword and those without. | |
| 1571 | /// | |
| 1572 | /// Static items cannot be moved: | |
| 1573 | /// | |
| 1574 | /// ```rust,compile_fail,E0507 | |
| 1575 | /// static VEC: Vec<u32> = vec![]; | |
| 1576 | /// | |
| 1577 | /// fn move_vec(v: Vec<u32>) -> Vec<u32> { | |
| 1578 | /// v | |
| 1579 | /// } | |
| 1580 | /// | |
| 1581 | /// // This line causes an error | |
| 1582 | /// move_vec(VEC); | |
| 1583 | /// ``` | |
| 1584 | /// | |
| 1585 | /// # Simple `static`s | |
| 1586 | /// | |
| 1587 | /// Accessing non-[`mut`] `static` items is considered safe, but some | |
| 1588 | /// restrictions apply. Most notably, the type of a `static` value needs to | |
| 1589 | /// implement the [`Sync`] trait, ruling out interior mutability containers | |
| 1590 | /// like [`RefCell`]. See the [Reference] for more information. | |
| 1591 | /// | |
| 1592 | /// ```rust | |
| 1593 | /// static FOO: [i32; 5] = [1, 2, 3, 4, 5]; | |
| 1594 | /// | |
| 1595 | /// let r1 = &FOO as *const _; | |
| 1596 | /// let r2 = &FOO as *const _; | |
| 1597 | /// // With a strictly read-only static, references will have the same address | |
| 1598 | /// assert_eq!(r1, r2); | |
| 1599 | /// // A static item can be used just like a variable in many cases | |
| 1600 | /// println!("{FOO:?}"); | |
| 1601 | /// ``` | |
| 1602 | /// | |
| 1603 | /// # Mutable `static`s | |
| 1604 | /// | |
| 1605 | /// If a `static` item is declared with the [`mut`] keyword, then it is allowed | |
| 1606 | /// to be modified by the program. However, accessing mutable `static`s can | |
| 1607 | /// cause undefined behavior in a number of ways, for example due to data races | |
| 1608 | /// in a multithreaded context. As such, all accesses to mutable `static`s | |
| 1609 | /// require an [`unsafe`] block. | |
| 1610 | /// | |
| 1611 | /// When possible, it's often better to use a non-mutable `static` with an | |
| 1612 | /// interior mutable type such as [`Mutex`], [`OnceLock`], or an [atomic]. | |
| 1613 | /// | |
| 1614 | /// Despite their unsafety, mutable `static`s are necessary in many contexts: | |
| 1615 | /// they can be used to represent global state shared by the whole program or in | |
| 1616 | /// [`extern`] blocks to bind to variables from C libraries. | |
| 1617 | /// | |
| 1618 | /// In an [`extern`] block: | |
| 1619 | /// | |
| 1620 | /// ```rust,no_run | |
| 1621 | /// # #![allow(dead_code)] | |
| 1622 | /// unsafe extern "C" { | |
| 1623 | /// static mut ERROR_MESSAGE: *mut std::os::raw::c_char; | |
| 1624 | /// } | |
| 1625 | /// ``` | |
| 1626 | /// | |
| 1627 | /// Mutable `static`s, just like simple `static`s, have some restrictions that | |
| 1628 | /// apply to them. See the [Reference] for more information. | |
| 1629 | /// | |
| 1630 | /// [`const`]: keyword.const.html | |
| 1631 | /// [`extern`]: keyword.extern.html | |
| 1632 | /// [`mut`]: keyword.mut.html | |
| 1633 | /// [`unsafe`]: keyword.unsafe.html | |
| 1634 | /// [`Mutex`]: sync::Mutex | |
| 1635 | /// [`OnceLock`]: sync::OnceLock | |
| 1636 | /// [`RefCell`]: cell::RefCell | |
| 1637 | /// [atomic]: sync::atomic | |
| 1638 | /// [Reference]: ../reference/items/static-items.html | |
| 1639 | mod static_keyword {} | |
| 1640 | ||
| 1641 | #[doc(keyword = "struct")] | |
| 1642 | // | |
| 1643 | /// A type that is composed of other types. | |
| 1644 | /// | |
| 1645 | /// Structs in Rust come in three flavors: Structs with named fields, tuple structs, and unit | |
| 1646 | /// structs. | |
| 1647 | /// | |
| 1648 | /// ```rust | |
| 1649 | /// struct Regular { | |
| 1650 | /// field1: f32, | |
| 1651 | /// field2: String, | |
| 1652 | /// pub field3: bool | |
| 1653 | /// } | |
| 1654 | /// | |
| 1655 | /// struct Tuple(u32, String); | |
| 1656 | /// | |
| 1657 | /// struct Unit; | |
| 1658 | /// ``` | |
| 1659 | /// | |
| 1660 | /// Regular structs are the most commonly used. Each field defined within them has a name and a | |
| 1661 | /// type, and once defined can be accessed using `example_struct.field` syntax. The fields of a | |
| 1662 | /// struct share its mutability, so `foo.bar = 2;` would only be valid if `foo` was mutable. Adding | |
| 1663 | /// `pub` to a field makes it visible to code in other modules, as well as allowing it to be | |
| 1664 | /// directly accessed and modified. | |
| 1665 | /// | |
| 1666 | /// Tuple structs are similar to regular structs, but its fields have no names. They are used like | |
| 1667 | /// tuples, with deconstruction possible via `let TupleStruct(x, y) = foo;` syntax. For accessing | |
| 1668 | /// individual variables, the same syntax is used as with regular tuples, namely `foo.0`, `foo.1`, | |
| 1669 | /// etc, starting at zero. | |
| 1670 | /// | |
| 1671 | /// Unit structs are most commonly used as marker. They have a size of zero bytes, but unlike empty | |
| 1672 | /// enums they can be instantiated, making them isomorphic to the unit type `()`. Unit structs are | |
| 1673 | /// useful when you need to implement a trait on something, but don't need to store any data inside | |
| 1674 | /// it. | |
| 1675 | /// | |
| 1676 | /// # Instantiation | |
| 1677 | /// | |
| 1678 | /// Structs can be instantiated in different ways, all of which can be mixed and | |
| 1679 | /// matched as needed. The most common way to make a new struct is via a constructor method such as | |
| 1680 | /// `new()`, but when that isn't available (or you're writing the constructor itself), struct | |
| 1681 | /// literal syntax is used: | |
| 1682 | /// | |
| 1683 | /// ```rust | |
| 1684 | /// # struct Foo { field1: f32, field2: String, etc: bool } | |
| 1685 | /// let example = Foo { | |
| 1686 | /// field1: 42.0, | |
| 1687 | /// field2: "blah".to_string(), | |
| 1688 | /// etc: true, | |
| 1689 | /// }; | |
| 1690 | /// ``` | |
| 1691 | /// | |
| 1692 | /// It's only possible to directly instantiate a struct using struct literal syntax when all of its | |
| 1693 | /// fields are visible to you. | |
| 1694 | /// | |
| 1695 | /// There are a handful of shortcuts provided to make writing constructors more convenient, most | |
| 1696 | /// common of which is the Field Init shorthand. When there is a variable and a field of the same | |
| 1697 | /// name, the assignment can be simplified from `field: field` into simply `field`. The following | |
| 1698 | /// example of a hypothetical constructor demonstrates this: | |
| 1699 | /// | |
| 1700 | /// ```rust | |
| 1701 | /// struct User { | |
| 1702 | /// name: String, | |
| 1703 | /// admin: bool, | |
| 1704 | /// } | |
| 1705 | /// | |
| 1706 | /// impl User { | |
| 1707 | /// pub fn new(name: String) -> Self { | |
| 1708 | /// Self { | |
| 1709 | /// name, | |
| 1710 | /// admin: false, | |
| 1711 | /// } | |
| 1712 | /// } | |
| 1713 | /// } | |
| 1714 | /// ``` | |
| 1715 | /// | |
| 1716 | /// Another shortcut for struct instantiation is available, used when you need to make a new | |
| 1717 | /// struct that has the same values as most of a previous struct of the same type, called struct | |
| 1718 | /// update syntax: | |
| 1719 | /// | |
| 1720 | /// ```rust | |
| 1721 | /// # struct Foo { field1: String, field2: () } | |
| 1722 | /// # let thing = Foo { field1: "".to_string(), field2: () }; | |
| 1723 | /// let updated_thing = Foo { | |
| 1724 | /// field1: "a new value".to_string(), | |
| 1725 | /// ..thing | |
| 1726 | /// }; | |
| 1727 | /// ``` | |
| 1728 | /// | |
| 1729 | /// Tuple structs are instantiated in the same way as tuples themselves, except with the struct's | |
| 1730 | /// name as a prefix: `Foo(123, false, 0.1)`. | |
| 1731 | /// | |
| 1732 | /// Empty structs are instantiated with just their name, and don't need anything else. `let thing = | |
| 1733 | /// EmptyStruct;` | |
| 1734 | /// | |
| 1735 | /// # Style conventions | |
| 1736 | /// | |
| 1737 | /// Structs are always written in UpperCamelCase, with few exceptions. While the trailing comma on a | |
| 1738 | /// struct's list of fields can be omitted, it's usually kept for convenience in adding and | |
| 1739 | /// removing fields down the line. | |
| 1740 | /// | |
| 1741 | /// For more information on structs, take a look at the [Rust Book][book] or the | |
| 1742 | /// [Reference][reference]. | |
| 1743 | /// | |
| 1744 | /// [`PhantomData`]: marker::PhantomData | |
| 1745 | /// [book]: ../book/ch05-01-defining-structs.html | |
| 1746 | /// [reference]: ../reference/items/structs.html | |
| 1747 | mod struct_keyword {} | |
| 1748 | ||
| 1749 | #[doc(keyword = "super")] | |
| 1750 | // | |
| 1751 | /// The parent of the current [module]. | |
| 1752 | /// | |
| 1753 | /// ```rust | |
| 1754 | /// # #![allow(dead_code)] | |
| 1755 | /// # fn main() {} | |
| 1756 | /// mod a { | |
| 1757 | /// pub fn foo() {} | |
| 1758 | /// } | |
| 1759 | /// mod b { | |
| 1760 | /// pub fn foo() { | |
| 1761 | /// super::a::foo(); // call a's foo function | |
| 1762 | /// } | |
| 1763 | /// } | |
| 1764 | /// ``` | |
| 1765 | /// | |
| 1766 | /// It is also possible to use `super` multiple times: `super::super::foo`, | |
| 1767 | /// going up the ancestor chain. | |
| 1768 | /// | |
| 1769 | /// See the [Reference] for more information. | |
| 1770 | /// | |
| 1771 | /// [module]: ../reference/items/modules.html | |
| 1772 | /// [Reference]: ../reference/paths.html#super | |
| 1773 | mod super_keyword {} | |
| 1774 | ||
| 1775 | #[doc(keyword = "trait")] | |
| 1776 | // | |
| 1777 | /// A common interface for a group of types. | |
| 1778 | /// | |
| 1779 | /// A `trait` is like an interface that data types can implement. When a type | |
| 1780 | /// implements a trait it can be treated abstractly as that trait using generics | |
| 1781 | /// or trait objects. | |
| 1782 | /// | |
| 1783 | /// Traits can be made up of three varieties of associated items: | |
| 1784 | /// | |
| 1785 | /// - functions and methods | |
| 1786 | /// - types | |
| 1787 | /// - constants | |
| 1788 | /// | |
| 1789 | /// Traits may also contain additional type parameters. Those type parameters | |
| 1790 | /// or the trait itself can be constrained by other traits. | |
| 1791 | /// | |
| 1792 | /// Traits can serve as markers or carry other logical semantics that | |
| 1793 | /// aren't expressed through their items. When a type implements that | |
| 1794 | /// trait it is promising to uphold its contract. [`Send`] and [`Sync`] are two | |
| 1795 | /// such marker traits present in the standard library. | |
| 1796 | /// | |
| 1797 | /// See the [Reference][Ref-Traits] for a lot more information on traits. | |
| 1798 | /// | |
| 1799 | /// # Examples | |
| 1800 | /// | |
| 1801 | /// Traits are declared using the `trait` keyword. Types can implement them | |
| 1802 | /// using [`impl`] `Trait` [`for`] `Type`: | |
| 1803 | /// | |
| 1804 | /// ```rust | |
| 1805 | /// trait Zero { | |
| 1806 | /// const ZERO: Self; | |
| 1807 | /// fn is_zero(&self) -> bool; | |
| 1808 | /// } | |
| 1809 | /// | |
| 1810 | /// impl Zero for i32 { | |
| 1811 | /// const ZERO: Self = 0; | |
| 1812 | /// | |
| 1813 | /// fn is_zero(&self) -> bool { | |
| 1814 | /// *self == Self::ZERO | |
| 1815 | /// } | |
| 1816 | /// } | |
| 1817 | /// | |
| 1818 | /// assert_eq!(i32::ZERO, 0); | |
| 1819 | /// assert!(i32::ZERO.is_zero()); | |
| 1820 | /// assert!(!4.is_zero()); | |
| 1821 | /// ``` | |
| 1822 | /// | |
| 1823 | /// With an associated type: | |
| 1824 | /// | |
| 1825 | /// ```rust | |
| 1826 | /// trait Builder { | |
| 1827 | /// type Built; | |
| 1828 | /// | |
| 1829 | /// fn build(&self) -> Self::Built; | |
| 1830 | /// } | |
| 1831 | /// ``` | |
| 1832 | /// | |
| 1833 | /// Traits can be generic, with constraints or without: | |
| 1834 | /// | |
| 1835 | /// ```rust | |
| 1836 | /// trait MaybeFrom<T> { | |
| 1837 | /// fn maybe_from(value: T) -> Option<Self> | |
| 1838 | /// where | |
| 1839 | /// Self: Sized; | |
| 1840 | /// } | |
| 1841 | /// ``` | |
| 1842 | /// | |
| 1843 | /// Traits can build upon the requirements of other traits. In the example | |
| 1844 | /// below `Iterator` is a **supertrait** and `ThreeIterator` is a **subtrait**: | |
| 1845 | /// | |
| 1846 | /// ```rust | |
| 1847 | /// trait ThreeIterator: Iterator { | |
| 1848 | /// fn next_three(&mut self) -> Option<[Self::Item; 3]>; | |
| 1849 | /// } | |
| 1850 | /// ``` | |
| 1851 | /// | |
| 1852 | /// Traits can be used in functions, as parameters: | |
| 1853 | /// | |
| 1854 | /// ```rust | |
| 1855 | /// # #![allow(dead_code)] | |
| 1856 | /// fn debug_iter<I: Iterator>(it: I) where I::Item: std::fmt::Debug { | |
| 1857 | /// for elem in it { | |
| 1858 | /// println!("{elem:#?}"); | |
| 1859 | /// } | |
| 1860 | /// } | |
| 1861 | /// | |
| 1862 | /// // u8_len_1, u8_len_2 and u8_len_3 are equivalent | |
| 1863 | /// | |
| 1864 | /// fn u8_len_1(val: impl Into<Vec<u8>>) -> usize { | |
| 1865 | /// val.into().len() | |
| 1866 | /// } | |
| 1867 | /// | |
| 1868 | /// fn u8_len_2<T: Into<Vec<u8>>>(val: T) -> usize { | |
| 1869 | /// val.into().len() | |
| 1870 | /// } | |
| 1871 | /// | |
| 1872 | /// fn u8_len_3<T>(val: T) -> usize | |
| 1873 | /// where | |
| 1874 | /// T: Into<Vec<u8>>, | |
| 1875 | /// { | |
| 1876 | /// val.into().len() | |
| 1877 | /// } | |
| 1878 | /// ``` | |
| 1879 | /// | |
| 1880 | /// Or as return types: | |
| 1881 | /// | |
| 1882 | /// ```rust | |
| 1883 | /// # #![allow(dead_code)] | |
| 1884 | /// fn from_zero_to(v: u8) -> impl Iterator<Item = u8> { | |
| 1885 | /// (0..v).into_iter() | |
| 1886 | /// } | |
| 1887 | /// ``` | |
| 1888 | /// | |
| 1889 | /// The use of the [`impl`] keyword in this position allows the function writer | |
| 1890 | /// to hide the concrete type as an implementation detail which can change | |
| 1891 | /// without breaking user's code. | |
| 1892 | /// | |
| 1893 | /// # Trait objects | |
| 1894 | /// | |
| 1895 | /// A *trait object* is an opaque value of another type that implements a set of | |
| 1896 | /// traits. A trait object implements all specified traits as well as their | |
| 1897 | /// supertraits (if any). | |
| 1898 | /// | |
| 1899 | /// The syntax is the following: `dyn BaseTrait + AutoTrait1 + ... AutoTraitN`. | |
| 1900 | /// Only one `BaseTrait` can be used so this will not compile: | |
| 1901 | /// | |
| 1902 | /// ```rust,compile_fail,E0225 | |
| 1903 | /// trait A {} | |
| 1904 | /// trait B {} | |
| 1905 | /// | |
| 1906 | /// let _: Box<dyn A + B>; | |
| 1907 | /// ``` | |
| 1908 | /// | |
| 1909 | /// Neither will this, which is a syntax error: | |
| 1910 | /// | |
| 1911 | /// ```rust,compile_fail | |
| 1912 | /// trait A {} | |
| 1913 | /// trait B {} | |
| 1914 | /// | |
| 1915 | /// let _: Box<dyn A + dyn B>; | |
| 1916 | /// ``` | |
| 1917 | /// | |
| 1918 | /// On the other hand, this is correct: | |
| 1919 | /// | |
| 1920 | /// ```rust | |
| 1921 | /// trait A {} | |
| 1922 | /// | |
| 1923 | /// let _: Box<dyn A + Send + Sync>; | |
| 1924 | /// ``` | |
| 1925 | /// | |
| 1926 | /// The [Reference][Ref-Trait-Objects] has more information about trait objects, | |
| 1927 | /// their limitations and the differences between editions. | |
| 1928 | /// | |
| 1929 | /// # Unsafe traits | |
| 1930 | /// | |
| 1931 | /// Some traits may be unsafe to implement. Using the [`unsafe`] keyword in | |
| 1932 | /// front of the trait's declaration is used to mark this: | |
| 1933 | /// | |
| 1934 | /// ```rust | |
| 1935 | /// unsafe trait UnsafeTrait {} | |
| 1936 | /// | |
| 1937 | /// unsafe impl UnsafeTrait for i32 {} | |
| 1938 | /// ``` | |
| 1939 | /// | |
| 1940 | /// # Differences between the 2015 and 2018 editions | |
| 1941 | /// | |
| 1942 | /// In the 2015 edition the parameters pattern was not needed for traits: | |
| 1943 | /// | |
| 1944 | /// ```rust,edition2015 | |
| 1945 | /// # #![allow(anonymous_parameters)] | |
| 1946 | /// trait Tr { | |
| 1947 | /// fn f(i32); | |
| 1948 | /// } | |
| 1949 | /// ``` | |
| 1950 | /// | |
| 1951 | /// This behavior is no longer valid in edition 2018. | |
| 1952 | /// | |
| 1953 | /// [`for`]: keyword.for.html | |
| 1954 | /// [`impl`]: keyword.impl.html | |
| 1955 | /// [`unsafe`]: keyword.unsafe.html | |
| 1956 | /// [Ref-Traits]: ../reference/items/traits.html | |
| 1957 | /// [Ref-Trait-Objects]: ../reference/types/trait-object.html | |
| 1958 | mod trait_keyword {} | |
| 1959 | ||
| 1960 | #[doc(keyword = "true")] | |
| 1961 | // | |
| 1962 | /// A value of type [`bool`] representing logical **true**. | |
| 1963 | /// | |
| 1964 | /// Logically `true` is not equal to [`false`]. | |
| 1965 | /// | |
| 1966 | /// ## Control structures that check for **true** | |
| 1967 | /// | |
| 1968 | /// Several of Rust's control structures will check for a `bool` condition evaluating to **true**. | |
| 1969 | /// | |
| 1970 | /// * The condition in an [`if`] expression must be of type `bool`. | |
| 1971 | /// Whenever that condition evaluates to **true**, the `if` expression takes | |
| 1972 | /// on the value of the first block. If however, the condition evaluates | |
| 1973 | /// to `false`, the expression takes on value of the `else` block if there is one. | |
| 1974 | /// | |
| 1975 | /// * [`while`] is another control flow construct expecting a `bool`-typed condition. | |
| 1976 | /// As long as the condition evaluates to **true**, the `while` loop will continually | |
| 1977 | /// evaluate its associated block. | |
| 1978 | /// | |
| 1979 | /// * [`match`] arms can have guard clauses on them. | |
| 1980 | /// | |
| 1981 | /// [`if`]: keyword.if.html | |
| 1982 | /// [`while`]: keyword.while.html | |
| 1983 | /// [`match`]: ../reference/expressions/match-expr.html#match-guards | |
| 1984 | /// [`false`]: keyword.false.html | |
| 1985 | mod true_keyword {} | |
| 1986 | ||
| 1987 | #[doc(keyword = "type")] | |
| 1988 | // | |
| 1989 | /// Define an [alias] for an existing type. | |
| 1990 | /// | |
| 1991 | /// The syntax is `type Name = ExistingType;`. | |
| 1992 | /// | |
| 1993 | /// # Examples | |
| 1994 | /// | |
| 1995 | /// `type` does **not** create a new type: | |
| 1996 | /// | |
| 1997 | /// ```rust | |
| 1998 | /// type Meters = u32; | |
| 1999 | /// type Kilograms = u32; | |
| 2000 | /// | |
| 2001 | /// let m: Meters = 3; | |
| 2002 | /// let k: Kilograms = 3; | |
| 2003 | /// | |
| 2004 | /// assert_eq!(m, k); | |
| 2005 | /// ``` | |
| 2006 | /// | |
| 2007 | /// A type can be generic: | |
| 2008 | /// | |
| 2009 | /// ```rust | |
| 2010 | /// # use std::sync::{Arc, Mutex}; | |
| 2011 | /// type ArcMutex<T> = Arc<Mutex<T>>; | |
| 2012 | /// ``` | |
| 2013 | /// | |
| 2014 | /// In traits, `type` is used to declare an [associated type]: | |
| 2015 | /// | |
| 2016 | /// ```rust | |
| 2017 | /// trait Iterator { | |
| 2018 | /// // associated type declaration | |
| 2019 | /// type Item; | |
| 2020 | /// fn next(&mut self) -> Option<Self::Item>; | |
| 2021 | /// } | |
| 2022 | /// | |
| 2023 | /// struct Once<T>(Option<T>); | |
| 2024 | /// | |
| 2025 | /// impl<T> Iterator for Once<T> { | |
| 2026 | /// // associated type definition | |
| 2027 | /// type Item = T; | |
| 2028 | /// fn next(&mut self) -> Option<Self::Item> { | |
| 2029 | /// self.0.take() | |
| 2030 | /// } | |
| 2031 | /// } | |
| 2032 | /// ``` | |
| 2033 | /// | |
| 2034 | /// [`trait`]: keyword.trait.html | |
| 2035 | /// [associated type]: ../reference/items/associated-items.html#associated-types | |
| 2036 | /// [alias]: ../reference/items/type-aliases.html | |
| 2037 | mod type_keyword {} | |
| 2038 | ||
| 2039 | #[doc(keyword = "unsafe")] | |
| 2040 | // | |
| 2041 | /// Code or interfaces whose [memory safety] cannot be verified by the type | |
| 2042 | /// system. | |
| 2043 | /// | |
| 2044 | /// The `unsafe` keyword has two uses: | |
| 2045 | /// - to declare the existence of contracts the compiler can't check, | |
| 2046 | /// - and to declare that a programmer has checked that these contracts have been upheld. | |
| 2047 | /// | |
| 2048 | /// Typically, each `unsafe` is either of the first or second kind: `unsafe fn` and `unsafe trait` | |
| 2049 | /// declare the existence of an unsafe contract; `unsafe {}` and `unsafe impl` declare that an | |
| 2050 | /// unsafe contract (which must have been declared elsewhere) is being upheld. | |
| 2051 | /// | |
| 2052 | /// However, historically, these two are not mutually exclusive: the body of an `unsafe fn` is, on | |
| 2053 | /// old editions, treated like an unsafe block, which means that this use of `unsafe` both declares | |
| 2054 | /// the existence of a contract to call the current function, and declares that the contracts of the | |
| 2055 | /// unsafe operations inside this function are being upheld. The `unsafe_op_in_unsafe_fn` lint can | |
| 2056 | /// be enabled to change that and make `unsafe fn` only play the former role. That lint is enabled | |
| 2057 | /// by default since edition 2024. | |
| 2058 | /// | |
| 2059 | /// # Unsafe abilities | |
| 2060 | /// | |
| 2061 | /// **No matter what, Safe Rust can't cause Undefined Behavior**. This is | |
| 2062 | /// referred to as [soundness]: a well-typed program actually has the desired | |
| 2063 | /// properties. The [Nomicon][nomicon-soundness] has a more detailed explanation | |
| 2064 | /// on the subject. | |
| 2065 | /// | |
| 2066 | /// To ensure soundness, Safe Rust is restricted enough that it can be | |
| 2067 | /// automatically checked. Sometimes, however, it is necessary to write code | |
| 2068 | /// that is correct for reasons which are too clever for the compiler to | |
| 2069 | /// understand. In those cases, you need to use Unsafe Rust. | |
| 2070 | /// | |
| 2071 | /// Here are the abilities Unsafe Rust has in addition to Safe Rust: | |
| 2072 | /// | |
| 2073 | /// - Dereference [raw pointers] | |
| 2074 | /// - Implement `unsafe` [`trait`]s | |
| 2075 | /// - Call `unsafe` functions | |
| 2076 | /// - Mutate [`static`]s (including [`extern`]al ones) | |
| 2077 | /// - Access fields of [`union`]s | |
| 2078 | /// | |
| 2079 | /// However, this extra power comes with extra responsibilities: it is now up to | |
| 2080 | /// you to ensure soundness. The `unsafe` keyword helps by clearly marking the | |
| 2081 | /// pieces of code that need to worry about this. | |
| 2082 | /// | |
| 2083 | /// ## The different meanings of `unsafe` | |
| 2084 | /// | |
| 2085 | /// Not all uses of `unsafe` are equivalent: some are here to mark the existence | |
| 2086 | /// of a contract the programmer must check, others are to say "I have checked | |
| 2087 | /// the contract, go ahead and do this". The following | |
| 2088 | /// [discussion on Rust Internals] has more in-depth explanations about this but | |
| 2089 | /// here is a summary of the main points: | |
| 2090 | /// | |
| 2091 | /// - `unsafe fn`: calling this function means abiding by a contract the | |
| 2092 | /// compiler cannot enforce. | |
| 2093 | /// - `unsafe trait`: implementing the [`trait`] means abiding by a | |
| 2094 | /// contract the compiler cannot enforce. | |
| 2095 | /// - `unsafe {}`: the contract necessary to call the operations inside the | |
| 2096 | /// block has been checked by the programmer and is guaranteed to be respected. | |
| 2097 | /// - `unsafe impl`: the contract necessary to implement the trait has been | |
| 2098 | /// checked by the programmer and is guaranteed to be respected. | |
| 2099 | /// | |
| 2100 | /// On old editions, `unsafe fn` also acts like an `unsafe {}` block around the code inside the | |
| 2101 | /// function. This means it is not just a signal to the caller, but also promises that the | |
| 2102 | /// preconditions for the operations inside the function are upheld. Mixing these two meanings can | |
| 2103 | /// be confusing, so the `unsafe_op_in_unsafe_fn` lint has been introduced and enabled by default | |
| 2104 | /// since edition 2024 to warn against that and require explicit unsafe blocks even inside `unsafe | |
| 2105 | /// fn`. | |
| 2106 | /// | |
| 2107 | /// See the [Rustonomicon] and the [Reference] for more information. | |
| 2108 | /// | |
| 2109 | /// # Examples | |
| 2110 | /// | |
| 2111 | /// ## Marking elements as `unsafe` | |
| 2112 | /// | |
| 2113 | /// `unsafe` can be used on functions. Note that functions and statics declared | |
| 2114 | /// in [`extern`] blocks are implicitly marked as `unsafe` (but not functions | |
| 2115 | /// declared as `extern "something" fn ...`). Mutable statics are always unsafe, | |
| 2116 | /// wherever they are declared. Methods can also be declared as `unsafe`: | |
| 2117 | /// | |
| 2118 | /// ```rust | |
| 2119 | /// # #![allow(dead_code)] | |
| 2120 | /// static mut FOO: &str = "hello"; | |
| 2121 | /// | |
| 2122 | /// unsafe fn unsafe_fn() {} | |
| 2123 | /// | |
| 2124 | /// unsafe extern "C" { | |
| 2125 | /// fn unsafe_extern_fn(); | |
| 2126 | /// static BAR: *mut u32; | |
| 2127 | /// } | |
| 2128 | /// | |
| 2129 | /// trait SafeTraitWithUnsafeMethod { | |
| 2130 | /// unsafe fn unsafe_method(&self); | |
| 2131 | /// } | |
| 2132 | /// | |
| 2133 | /// struct S; | |
| 2134 | /// | |
| 2135 | /// impl S { | |
| 2136 | /// unsafe fn unsafe_method_on_struct() {} | |
| 2137 | /// } | |
| 2138 | /// ``` | |
| 2139 | /// | |
| 2140 | /// Traits can also be declared as `unsafe`: | |
| 2141 | /// | |
| 2142 | /// ```rust | |
| 2143 | /// unsafe trait UnsafeTrait {} | |
| 2144 | /// ``` | |
| 2145 | /// | |
| 2146 | /// Since `unsafe fn` and `unsafe trait` indicate that there is a safety | |
| 2147 | /// contract that the compiler cannot enforce, documenting it is important. The | |
| 2148 | /// standard library has many examples of this, like the following which is an | |
| 2149 | /// extract from [`Vec::set_len`]. The `# Safety` section explains the contract | |
| 2150 | /// that must be fulfilled to safely call the function. | |
| 2151 | /// | |
| 2152 | /// ```rust,ignore (stub-to-show-doc-example) | |
| 2153 | /// /// Forces the length of the vector to `new_len`. | |
| 2154 | /// /// | |
| 2155 | /// /// This is a low-level operation that maintains none of the normal | |
| 2156 | /// /// invariants of the type. Normally changing the length of a vector | |
| 2157 | /// /// is done using one of the safe operations instead, such as | |
| 2158 | /// /// `truncate`, `resize`, `extend`, or `clear`. | |
| 2159 | /// /// | |
| 2160 | /// /// # Safety | |
| 2161 | /// /// | |
| 2162 | /// /// - `new_len` must be less than or equal to `capacity()`. | |
| 2163 | /// /// - The elements at `old_len..new_len` must be initialized. | |
| 2164 | /// pub unsafe fn set_len(&mut self, new_len: usize) | |
| 2165 | /// ``` | |
| 2166 | /// | |
| 2167 | /// ## Using `unsafe {}` blocks and `impl`s | |
| 2168 | /// | |
| 2169 | /// Performing `unsafe` operations requires an `unsafe {}` block: | |
| 2170 | /// | |
| 2171 | /// ```rust | |
| 2172 | /// # #![allow(dead_code)] | |
| 2173 | /// #![deny(unsafe_op_in_unsafe_fn)] | |
| 2174 | /// | |
| 2175 | /// /// Dereference the given pointer. | |
| 2176 | /// /// | |
| 2177 | /// /// # Safety | |
| 2178 | /// /// | |
| 2179 | /// /// `ptr` must be aligned and must not be dangling. | |
| 2180 | /// unsafe fn deref_unchecked(ptr: *const i32) -> i32 { | |
| 2181 | /// // SAFETY: the caller is required to ensure that `ptr` is aligned and dereferenceable. | |
| 2182 | /// unsafe { *ptr } | |
| 2183 | /// } | |
| 2184 | /// | |
| 2185 | /// let a = 3; | |
| 2186 | /// let b = &a as *const _; | |
| 2187 | /// // SAFETY: `a` has not been dropped and references are always aligned, | |
| 2188 | /// // so `b` is a valid address. | |
| 2189 | /// unsafe { assert_eq!(*b, deref_unchecked(b)); }; | |
| 2190 | /// ``` | |
| 2191 | /// | |
| 2192 | /// ## `unsafe` and traits | |
| 2193 | /// | |
| 2194 | /// The interactions of `unsafe` and traits can be surprising, so let us contrast the | |
| 2195 | /// two combinations of safe `fn` in `unsafe trait` and `unsafe fn` in safe trait using two | |
| 2196 | /// examples: | |
| 2197 | /// | |
| 2198 | /// ```rust | |
| 2199 | /// /// # Safety | |
| 2200 | /// /// | |
| 2201 | /// /// `make_even` must return an even number. | |
| 2202 | /// unsafe trait MakeEven { | |
| 2203 | /// fn make_even(&self) -> i32; | |
| 2204 | /// } | |
| 2205 | /// | |
| 2206 | /// // SAFETY: Our `make_even` always returns something even. | |
| 2207 | /// unsafe impl MakeEven for i32 { | |
| 2208 | /// fn make_even(&self) -> i32 { | |
| 2209 | /// self << 1 | |
| 2210 | /// } | |
| 2211 | /// } | |
| 2212 | /// | |
| 2213 | /// fn use_make_even(x: impl MakeEven) { | |
| 2214 | /// if x.make_even() % 2 == 1 { | |
| 2215 | /// // SAFETY: this can never happen, because all `MakeEven` implementations | |
| 2216 | /// // ensure that `make_even` returns something even. | |
| 2217 | /// unsafe { std::hint::unreachable_unchecked() }; | |
| 2218 | /// } | |
| 2219 | /// } | |
| 2220 | /// ``` | |
| 2221 | /// | |
| 2222 | /// Note how the safety contract of the trait is upheld by the implementation, and is itself used to | |
| 2223 | /// uphold the safety contract of the unsafe function `unreachable_unchecked` called by | |
| 2224 | /// `use_make_even`. `make_even` itself is a safe function because its *callers* do not have to | |
| 2225 | /// worry about any contract, only the *implementation* of `MakeEven` is required to uphold a | |
| 2226 | /// certain contract. `use_make_even` is safe because it can use the promise made by `MakeEven` | |
| 2227 | /// implementations to uphold the safety contract of the `unsafe fn unreachable_unchecked` it calls. | |
| 2228 | /// | |
| 2229 | /// It is also possible to have `unsafe fn` in a regular safe `trait`: | |
| 2230 | /// | |
| 2231 | /// ```rust | |
| 2232 | /// # #![feature(never_type)] | |
| 2233 | /// #![deny(unsafe_op_in_unsafe_fn)] | |
| 2234 | /// | |
| 2235 | /// trait Indexable { | |
| 2236 | /// const LEN: usize; | |
| 2237 | /// | |
| 2238 | /// /// # Safety | |
| 2239 | /// /// | |
| 2240 | /// /// The caller must ensure that `idx < LEN`. | |
| 2241 | /// unsafe fn idx_unchecked(&self, idx: usize) -> i32; | |
| 2242 | /// } | |
| 2243 | /// | |
| 2244 | /// // The implementation for `i32` doesn't need to do any contract reasoning. | |
| 2245 | /// impl Indexable for i32 { | |
| 2246 | /// const LEN: usize = 1; | |
| 2247 | /// | |
| 2248 | /// /// See `Indexable` for the safety contract. | |
| 2249 | /// unsafe fn idx_unchecked(&self, idx: usize) -> i32 { | |
| 2250 | /// debug_assert_eq!(idx, 0); | |
| 2251 | /// *self | |
| 2252 | /// } | |
| 2253 | /// } | |
| 2254 | /// | |
| 2255 | /// // The implementation for arrays exploits the function contract to | |
| 2256 | /// // make use of `get_unchecked` on slices and avoid a run-time check. | |
| 2257 | /// impl Indexable for [i32; 42] { | |
| 2258 | /// const LEN: usize = 42; | |
| 2259 | /// | |
| 2260 | /// /// See `Indexable` for the safety contract. | |
| 2261 | /// unsafe fn idx_unchecked(&self, idx: usize) -> i32 { | |
| 2262 | /// // SAFETY: As per this trait's documentation, the caller ensures | |
| 2263 | /// // that `idx < 42`. | |
| 2264 | /// unsafe { *self.get_unchecked(idx) } | |
| 2265 | /// } | |
| 2266 | /// } | |
| 2267 | /// | |
| 2268 | /// // The implementation for the never type declares a length of 0, | |
| 2269 | /// // which means `idx_unchecked` can never be called. | |
| 2270 | /// impl Indexable for ! { | |
| 2271 | /// const LEN: usize = 0; | |
| 2272 | /// | |
| 2273 | /// /// See `Indexable` for the safety contract. | |
| 2274 | /// unsafe fn idx_unchecked(&self, idx: usize) -> i32 { | |
| 2275 | /// // SAFETY: As per this trait's documentation, the caller ensures | |
| 2276 | /// // that `idx < 0`, which is impossible, so this is dead code. | |
| 2277 | /// unsafe { std::hint::unreachable_unchecked() } | |
| 2278 | /// } | |
| 2279 | /// } | |
| 2280 | /// | |
| 2281 | /// fn use_indexable<I: Indexable>(x: I, idx: usize) -> i32 { | |
| 2282 | /// if idx < I::LEN { | |
| 2283 | /// // SAFETY: We have checked that `idx < I::LEN`. | |
| 2284 | /// unsafe { x.idx_unchecked(idx) } | |
| 2285 | /// } else { | |
| 2286 | /// panic!("index out-of-bounds") | |
| 2287 | /// } | |
| 2288 | /// } | |
| 2289 | /// ``` | |
| 2290 | /// | |
| 2291 | /// This time, `use_indexable` is safe because it uses a run-time check to discharge the safety | |
| 2292 | /// contract of `idx_unchecked`. Implementing `Indexable` is safe because when writing | |
| 2293 | /// `idx_unchecked`, we don't have to worry: our *callers* need to discharge a proof obligation | |
| 2294 | /// (like `use_indexable` does), but the *implementation* of `get_unchecked` has no proof obligation | |
| 2295 | /// to contend with. Of course, the implementation may choose to call other unsafe operations, and | |
| 2296 | /// then it needs an `unsafe` *block* to indicate it discharged the proof obligations of its | |
| 2297 | /// callees. For that purpose it can make use of the contract that all its callers must uphold -- | |
| 2298 | /// the fact that `idx < LEN`. | |
| 2299 | /// | |
| 2300 | /// Note that unlike normal `unsafe fn`, an `unsafe fn` in a trait implementation does not get to | |
| 2301 | /// just pick an arbitrary safety contract! It *has* to use the safety contract defined by the trait | |
| 2302 | /// (or one with weaker preconditions). | |
| 2303 | /// | |
| 2304 | /// Formally speaking, an `unsafe fn` in a trait is a function with *preconditions* that go beyond | |
| 2305 | /// those encoded by the argument types (such as `idx < LEN`), whereas an `unsafe trait` can declare | |
| 2306 | /// that some of its functions have *postconditions* that go beyond those encoded in the return type | |
| 2307 | /// (such as returning an even integer). If a trait needs a function with both extra precondition | |
| 2308 | /// and extra postcondition, then it needs an `unsafe fn` in an `unsafe trait`. | |
| 2309 | /// | |
| 2310 | /// [`extern`]: keyword.extern.html | |
| 2311 | /// [`trait`]: keyword.trait.html | |
| 2312 | /// [`static`]: keyword.static.html | |
| 2313 | /// [`union`]: keyword.union.html | |
| 2314 | /// [`impl`]: keyword.impl.html | |
| 2315 | /// [raw pointers]: ../reference/types/pointer.html | |
| 2316 | /// [memory safety]: ../book/ch19-01-unsafe-rust.html | |
| 2317 | /// [Rustonomicon]: ../nomicon/index.html | |
| 2318 | /// [nomicon-soundness]: ../nomicon/safe-unsafe-meaning.html | |
| 2319 | /// [soundness]: https://rust-lang.github.io/unsafe-code-guidelines/glossary.html#soundness-of-code--of-a-library | |
| 2320 | /// [Reference]: ../reference/unsafety.html | |
| 2321 | /// [discussion on Rust Internals]: https://internals.rust-lang.org/t/what-does-unsafe-mean/6696 | |
| 2322 | mod unsafe_keyword {} | |
| 2323 | ||
| 2324 | #[doc(keyword = "use")] | |
| 2325 | // | |
| 2326 | /// Import or rename items from other crates or modules, use values under ergonomic clones | |
| 2327 | /// semantic, or specify precise capturing with `use<..>`. | |
| 2328 | /// | |
| 2329 | /// ## Importing items | |
| 2330 | /// | |
| 2331 | /// The `use` keyword is employed to shorten the path required to refer to a module item. | |
| 2332 | /// The keyword may appear in modules, blocks, and even functions, typically at the top. | |
| 2333 | /// | |
| 2334 | /// The most basic usage of the keyword is `use path::to::item;`, | |
| 2335 | /// though a number of convenient shortcuts are supported: | |
| 2336 | /// | |
| 2337 | /// * Simultaneously binding a list of paths with a common prefix, | |
| 2338 | /// using the glob-like brace syntax `use a::b::{c, d, e::f, g::h::i};` | |
| 2339 | /// * Simultaneously binding a list of paths with a common prefix and their common parent module, | |
| 2340 | /// using the [`self`] keyword, such as `use a::b::{self, c, d::e};` | |
| 2341 | /// * Rebinding the target name as a new local name, using the syntax `use p::q::r as x;`. | |
| 2342 | /// This can also be used with the last two features: `use a::b::{self as ab, c as abc}`. | |
| 2343 | /// * Binding all paths matching a given prefix, | |
| 2344 | /// using the asterisk wildcard syntax `use a::b::*;`. | |
| 2345 | /// * Nesting groups of the previous features multiple times, | |
| 2346 | /// such as `use a::b::{self as ab, c, d::{*, e::f}};` | |
| 2347 | /// * Reexporting with visibility modifiers such as `pub use a::b;` | |
| 2348 | /// * Importing with `_` to only import the methods of a trait without binding it to a name | |
| 2349 | /// (to avoid conflict for example): `use ::std::io::Read as _;`. | |
| 2350 | /// | |
| 2351 | /// Using path qualifiers like [`crate`], [`super`] or [`self`] is supported: `use crate::a::b;`. | |
| 2352 | /// | |
| 2353 | /// Note that when the wildcard `*` is used on a type, it does not import its methods (though | |
| 2354 | /// for `enum`s it imports the variants, as shown in the example below). | |
| 2355 | /// | |
| 2356 | /// ```compile_fail,edition2018 | |
| 2357 | /// enum ExampleEnum { | |
| 2358 | /// VariantA, | |
| 2359 | /// VariantB, | |
| 2360 | /// } | |
| 2361 | /// | |
| 2362 | /// impl ExampleEnum { | |
| 2363 | /// fn new() -> Self { | |
| 2364 | /// Self::VariantA | |
| 2365 | /// } | |
| 2366 | /// } | |
| 2367 | /// | |
| 2368 | /// use ExampleEnum::*; | |
| 2369 | /// | |
| 2370 | /// // Compiles. | |
| 2371 | /// let _ = VariantA; | |
| 2372 | /// | |
| 2373 | /// // Does not compile! | |
| 2374 | /// let n = new(); | |
| 2375 | /// ``` | |
| 2376 | /// | |
| 2377 | /// For more information on `use` and paths in general, see the [Reference][ref-use-decls]. | |
| 2378 | /// | |
| 2379 | /// The differences about paths and the `use` keyword between the 2015 and 2018 editions | |
| 2380 | /// can also be found in the [Reference][ref-use-decls]. | |
| 2381 | /// | |
| 2382 | /// ## Precise capturing | |
| 2383 | /// | |
| 2384 | /// The `use<..>` syntax is used within certain `impl Trait` bounds to control which generic | |
| 2385 | /// parameters are captured. This is important for return-position `impl Trait` (RPIT) types, | |
| 2386 | /// as it affects borrow checking by controlling which generic parameters can be used in the | |
| 2387 | /// hidden type. | |
| 2388 | /// | |
| 2389 | /// For example, the following function demonstrates an error without precise capturing in | |
| 2390 | /// Rust 2021 and earlier editions: | |
| 2391 | /// | |
| 2392 | /// ```rust,compile_fail,edition2021 | |
| 2393 | /// fn f(x: &()) -> impl Sized { x } | |
| 2394 | /// ``` | |
| 2395 | /// | |
| 2396 | /// By using `use<'_>` for precise capturing, it can be resolved: | |
| 2397 | /// | |
| 2398 | /// ```rust | |
| 2399 | /// fn f(x: &()) -> impl Sized + use<'_> { x } | |
| 2400 | /// ``` | |
| 2401 | /// | |
| 2402 | /// This syntax specifies that the elided lifetime be captured and therefore available for | |
| 2403 | /// use in the hidden type. | |
| 2404 | /// | |
| 2405 | /// In Rust 2024, opaque types automatically capture all lifetime parameters in scope. | |
| 2406 | /// `use<..>` syntax serves as an important way of opting-out of that default. | |
| 2407 | /// | |
| 2408 | /// For more details about precise capturing, see the [Reference][ref-impl-trait]. | |
| 2409 | /// | |
| 2410 | /// ## Ergonomic clones | |
| 2411 | /// | |
| 2412 | /// Use a values, copying its content if the value implements `Copy`, cloning the contents if the | |
| 2413 | /// value implements `UseCloned` or moving it otherwise. | |
| 2414 | /// | |
| 2415 | /// [`crate`]: keyword.crate.html | |
| 2416 | /// [`self`]: keyword.self.html | |
| 2417 | /// [`super`]: keyword.super.html | |
| 2418 | /// [ref-use-decls]: ../reference/items/use-declarations.html | |
| 2419 | /// [ref-impl-trait]: ../reference/types/impl-trait.html | |
| 2420 | mod use_keyword {} | |
| 2421 | ||
| 2422 | #[doc(keyword = "where")] | |
| 2423 | // | |
| 2424 | /// Add constraints that must be upheld to use an item. | |
| 2425 | /// | |
| 2426 | /// `where` allows specifying constraints on lifetime and generic parameters. | |
| 2427 | /// The [RFC] introducing `where` contains detailed information about the | |
| 2428 | /// keyword. | |
| 2429 | /// | |
| 2430 | /// # Examples | |
| 2431 | /// | |
| 2432 | /// `where` can be used for constraints with traits: | |
| 2433 | /// | |
| 2434 | /// ```rust | |
| 2435 | /// fn new<T: Default>() -> T { | |
| 2436 | /// T::default() | |
| 2437 | /// } | |
| 2438 | /// | |
| 2439 | /// fn new_where<T>() -> T | |
| 2440 | /// where | |
| 2441 | /// T: Default, | |
| 2442 | /// { | |
| 2443 | /// T::default() | |
| 2444 | /// } | |
| 2445 | /// | |
| 2446 | /// assert_eq!(0.0, new()); | |
| 2447 | /// assert_eq!(0.0, new_where()); | |
| 2448 | /// | |
| 2449 | /// assert_eq!(0, new()); | |
| 2450 | /// assert_eq!(0, new_where()); | |
| 2451 | /// ``` | |
| 2452 | /// | |
| 2453 | /// `where` can also be used for lifetimes. | |
| 2454 | /// | |
| 2455 | /// This compiles because `longer` outlives `shorter`, thus the constraint is | |
| 2456 | /// respected: | |
| 2457 | /// | |
| 2458 | /// ```rust | |
| 2459 | /// fn select<'short, 'long>(s1: &'short str, s2: &'long str, second: bool) -> &'short str | |
| 2460 | /// where | |
| 2461 | /// 'long: 'short, | |
| 2462 | /// { | |
| 2463 | /// if second { s2 } else { s1 } | |
| 2464 | /// } | |
| 2465 | /// | |
| 2466 | /// let outer = String::from("Long living ref"); | |
| 2467 | /// let longer = &outer; | |
| 2468 | /// { | |
| 2469 | /// let inner = String::from("Short living ref"); | |
| 2470 | /// let shorter = &inner; | |
| 2471 | /// | |
| 2472 | /// assert_eq!(select(shorter, longer, false), shorter); | |
| 2473 | /// assert_eq!(select(shorter, longer, true), longer); | |
| 2474 | /// } | |
| 2475 | /// ``` | |
| 2476 | /// | |
| 2477 | /// On the other hand, this will not compile because the `where 'b: 'a` clause | |
| 2478 | /// is missing: the `'b` lifetime is not known to live at least as long as `'a` | |
| 2479 | /// which means this function cannot ensure it always returns a valid reference: | |
| 2480 | /// | |
| 2481 | /// ```rust,compile_fail | |
| 2482 | /// fn select<'a, 'b>(s1: &'a str, s2: &'b str, second: bool) -> &'a str | |
| 2483 | /// { | |
| 2484 | /// if second { s2 } else { s1 } | |
| 2485 | /// } | |
| 2486 | /// ``` | |
| 2487 | /// | |
| 2488 | /// `where` can also be used to express more complicated constraints that cannot | |
| 2489 | /// be written with the `<T: Trait>` syntax: | |
| 2490 | /// | |
| 2491 | /// ```rust | |
| 2492 | /// fn first_or_default<I>(mut i: I) -> I::Item | |
| 2493 | /// where | |
| 2494 | /// I: Iterator, | |
| 2495 | /// I::Item: Default, | |
| 2496 | /// { | |
| 2497 | /// i.next().unwrap_or_else(I::Item::default) | |
| 2498 | /// } | |
| 2499 | /// | |
| 2500 | /// assert_eq!(first_or_default([1, 2, 3].into_iter()), 1); | |
| 2501 | /// assert_eq!(first_or_default(Vec::<i32>::new().into_iter()), 0); | |
| 2502 | /// ``` | |
| 2503 | /// | |
| 2504 | /// `where` is available anywhere generic and lifetime parameters are available, | |
| 2505 | /// as can be seen with the [`Cow`](crate::borrow::Cow) type from the standard | |
| 2506 | /// library: | |
| 2507 | /// | |
| 2508 | /// ```rust | |
| 2509 | /// # #![allow(dead_code)] | |
| 2510 | /// pub enum Cow<'a, B> | |
| 2511 | /// where | |
| 2512 | /// B: ToOwned + ?Sized, | |
| 2513 | /// { | |
| 2514 | /// Borrowed(&'a B), | |
| 2515 | /// Owned(<B as ToOwned>::Owned), | |
| 2516 | /// } | |
| 2517 | /// ``` | |
| 2518 | /// | |
| 2519 | /// [RFC]: https://github.com/rust-lang/rfcs/blob/master/text/0135-where.md | |
| 2520 | mod where_keyword {} | |
| 2521 | ||
| 2522 | #[doc(keyword = "while")] | |
| 2523 | // | |
| 2524 | /// Loop while a condition is upheld. | |
| 2525 | /// | |
| 2526 | /// A `while` expression is used for predicate loops. The `while` expression runs the conditional | |
| 2527 | /// expression before running the loop body, then runs the loop body if the conditional | |
| 2528 | /// expression evaluates to `true`, or exits the loop otherwise. | |
| 2529 | /// | |
| 2530 | /// ```rust | |
| 2531 | /// let mut counter = 0; | |
| 2532 | /// | |
| 2533 | /// while counter < 10 { | |
| 2534 | /// println!("{counter}"); | |
| 2535 | /// counter += 1; | |
| 2536 | /// } | |
| 2537 | /// ``` | |
| 2538 | /// | |
| 2539 | /// Like the [`for`] expression, we can use `break` and `continue`. A `while` expression | |
| 2540 | /// cannot break with a value and always evaluates to `()` unlike [`loop`]. | |
| 2541 | /// | |
| 2542 | /// ```rust | |
| 2543 | /// let mut i = 1; | |
| 2544 | /// | |
| 2545 | /// while i < 100 { | |
| 2546 | /// i *= 2; | |
| 2547 | /// if i == 64 { | |
| 2548 | /// break; // Exit when `i` is 64. | |
| 2549 | /// } | |
| 2550 | /// } | |
| 2551 | /// ``` | |
| 2552 | /// | |
| 2553 | /// As `if` expressions have their pattern matching variant in `if let`, so too do `while` | |
| 2554 | /// expressions with `while let`. The `while let` expression matches the pattern against the | |
| 2555 | /// expression, then runs the loop body if pattern matching succeeds, or exits the loop otherwise. | |
| 2556 | /// We can use `break` and `continue` in `while let` expressions just like in `while`. | |
| 2557 | /// | |
| 2558 | /// ```rust | |
| 2559 | /// let mut counter = Some(0); | |
| 2560 | /// | |
| 2561 | /// while let Some(i) = counter { | |
| 2562 | /// if i == 10 { | |
| 2563 | /// counter = None; | |
| 2564 | /// } else { | |
| 2565 | /// println!("{i}"); | |
| 2566 | /// counter = Some (i + 1); | |
| 2567 | /// } | |
| 2568 | /// } | |
| 2569 | /// ``` | |
| 2570 | /// | |
| 2571 | /// For more information on `while` and loops in general, see the [reference]. | |
| 2572 | /// | |
| 2573 | /// See also, [`for`], [`loop`]. | |
| 2574 | /// | |
| 2575 | /// [`for`]: keyword.for.html | |
| 2576 | /// [`loop`]: keyword.loop.html | |
| 2577 | /// [reference]: ../reference/expressions/loop-expr.html#predicate-loops | |
| 2578 | mod while_keyword {} | |
| 2579 | ||
| 2580 | // 2018 Edition keywords | |
| 2581 | ||
| 2582 | #[doc(alias = "promise")] | |
| 2583 | #[doc(keyword = "async")] | |
| 2584 | // | |
| 2585 | /// Returns a [`Future`] instead of blocking the current thread. | |
| 2586 | /// | |
| 2587 | /// Use `async` in front of `fn`, `closure`, or a `block` to turn the marked code into a `Future`. | |
| 2588 | /// As such the code will not be run immediately, but will only be evaluated when the returned | |
| 2589 | /// future is [`.await`]ed. | |
| 2590 | /// | |
| 2591 | /// We have written an [async book] detailing `async`/`await` and trade-offs compared to using threads. | |
| 2592 | /// | |
| 2593 | /// ## Control Flow | |
| 2594 | /// [`return`] statements and [`?`][try operator] operators within `async` blocks do not cause | |
| 2595 | /// a return from the parent function; rather, they cause the `Future` returned by the block to | |
| 2596 | /// return with that value. | |
| 2597 | /// | |
| 2598 | /// For example, the following Rust function will return `5`, causing `x` to take the [`!` type][never type]: | |
| 2599 | /// ```rust | |
| 2600 | /// #[expect(unused_variables)] | |
| 2601 | /// fn example() -> i32 { | |
| 2602 | /// let x = { | |
| 2603 | /// return 5; | |
| 2604 | /// }; | |
| 2605 | /// } | |
| 2606 | /// ``` | |
| 2607 | /// In contrast, the following asynchronous function assigns a `Future<Output = i32>` to `x`, and | |
| 2608 | /// only returns `5` when `x` is `.await`ed: | |
| 2609 | /// ```rust | |
| 2610 | /// async fn example() -> i32 { | |
| 2611 | /// let x = async { | |
| 2612 | /// return 5; | |
| 2613 | /// }; | |
| 2614 | /// | |
| 2615 | /// x.await | |
| 2616 | /// } | |
| 2617 | /// ``` | |
| 2618 | /// Code using `?` behaves similarly - it causes the `async` block to return a [`Result`] without | |
| 2619 | /// affecting the parent function. | |
| 2620 | /// | |
| 2621 | /// Note that you cannot use `break` or `continue` from within an `async` block to affect the | |
| 2622 | /// control flow of a loop in the parent function. | |
| 2623 | /// | |
| 2624 | /// Control flow in `async` blocks is documented further in the [async book][async book blocks]. | |
| 2625 | /// | |
| 2626 | /// ## Editions | |
| 2627 | /// | |
| 2628 | /// `async` is a keyword from the 2018 edition onwards. | |
| 2629 | /// | |
| 2630 | /// It is available for use in stable Rust from version 1.39 onwards. | |
| 2631 | /// | |
| 2632 | /// [`Future`]: future::Future | |
| 2633 | /// [`.await`]: ../std/keyword.await.html | |
| 2634 | /// [async book]: https://rust-lang.github.io/async-book/ | |
| 2635 | /// [`return`]: ../std/keyword.return.html | |
| 2636 | /// [try operator]: ../reference/expressions/operator-expr.html#r-expr.try | |
| 2637 | /// [never type]: ../reference/types/never.html | |
| 2638 | /// [`Result`]: result::Result | |
| 2639 | /// [async book blocks]: https://rust-lang.github.io/async-book/part-guide/more-async-await.html#async-blocks | |
| 2640 | mod async_keyword {} | |
| 2641 | ||
| 2642 | #[doc(keyword = "await")] | |
| 2643 | // | |
| 2644 | /// Suspend execution until the result of a [`Future`] is ready. | |
| 2645 | /// | |
| 2646 | /// `.await`ing a future will suspend the current function's execution until the executor | |
| 2647 | /// has run the future to completion. | |
| 2648 | /// | |
| 2649 | /// Read the [async book] for details on how [`async`]/`await` and executors work. | |
| 2650 | /// | |
| 2651 | /// ## Editions | |
| 2652 | /// | |
| 2653 | /// `await` is a keyword from the 2018 edition onwards. | |
| 2654 | /// | |
| 2655 | /// It is available for use in stable Rust from version 1.39 onwards. | |
| 2656 | /// | |
| 2657 | /// [`Future`]: future::Future | |
| 2658 | /// [async book]: https://rust-lang.github.io/async-book/ | |
| 2659 | /// [`async`]: ../std/keyword.async.html | |
| 2660 | mod await_keyword {} | |
| 2661 | ||
| 2662 | #[doc(keyword = "dyn")] | |
| 2663 | // | |
| 2664 | /// `dyn` is a prefix of a [trait object]'s type. | |
| 2665 | /// | |
| 2666 | /// The `dyn` keyword is used to highlight that calls to methods on the associated `Trait` | |
| 2667 | /// are [dynamically dispatched]. To use the trait this way, it must be *dyn compatible*[^1]. | |
| 2668 | /// | |
| 2669 | /// Unlike generic parameters or `impl Trait`, the compiler does not know the concrete type that | |
| 2670 | /// is being passed. That is, the type has been [erased]. | |
| 2671 | /// As such, a `dyn Trait` reference contains _two_ pointers. | |
| 2672 | /// One pointer goes to the data (e.g., an instance of a struct). | |
| 2673 | /// Another pointer goes to a map of method call names to function pointers | |
| 2674 | /// (known as a virtual method table or vtable). | |
| 2675 | /// | |
| 2676 | /// At run-time, when a method needs to be called on the `dyn Trait`, the vtable is consulted to get | |
| 2677 | /// the function pointer and then that function pointer is called. | |
| 2678 | /// | |
| 2679 | /// See the Reference for more information on [trait objects][ref-trait-obj] | |
| 2680 | /// and [dyn compatibility][ref-dyn-compat]. | |
| 2681 | /// | |
| 2682 | /// ## Trade-offs | |
| 2683 | /// | |
| 2684 | /// The above indirection is the additional runtime cost of calling a function on a `dyn Trait`. | |
| 2685 | /// Methods called by dynamic dispatch generally cannot be inlined by the compiler. | |
| 2686 | /// | |
| 2687 | /// However, `dyn Trait` is likely to produce smaller code than `impl Trait` / generic parameters as | |
| 2688 | /// the method won't be duplicated for each concrete type. | |
| 2689 | /// | |
| 2690 | /// [trait object]: ../book/ch17-02-trait-objects.html | |
| 2691 | /// [dynamically dispatched]: https://en.wikipedia.org/wiki/Dynamic_dispatch | |
| 2692 | /// [ref-trait-obj]: ../reference/types/trait-object.html | |
| 2693 | /// [ref-dyn-compat]: ../reference/items/traits.html#dyn-compatibility | |
| 2694 | /// [erased]: https://en.wikipedia.org/wiki/Type_erasure | |
| 2695 | /// [^1]: Formerly known as *object safe*. | |
| 2696 | mod dyn_keyword {} | |
| 2697 | ||
| 2698 | #[doc(keyword = "union")] | |
| 2699 | // | |
| 2700 | /// The [Rust equivalent of a C-style union][union]. | |
| 2701 | /// | |
| 2702 | /// A `union` looks like a [`struct`] in terms of declaration, but all of its | |
| 2703 | /// fields exist in the same memory, superimposed over one another. For instance, | |
| 2704 | /// if we wanted some bits in memory that we sometimes interpret as a `u32` and | |
| 2705 | /// sometimes as an `f32`, we could write: | |
| 2706 | /// | |
| 2707 | /// ```rust | |
| 2708 | /// union IntOrFloat { | |
| 2709 | /// i: u32, | |
| 2710 | /// f: f32, | |
| 2711 | /// } | |
| 2712 | /// | |
| 2713 | /// let mut u = IntOrFloat { f: 1.0 }; | |
| 2714 | /// // Reading the fields of a union is always unsafe | |
| 2715 | /// assert_eq!(unsafe { u.i }, 1065353216); | |
| 2716 | /// // Updating through any of the field will modify all of them | |
| 2717 | /// u.i = 1073741824; | |
| 2718 | /// assert_eq!(unsafe { u.f }, 2.0); | |
| 2719 | /// ``` | |
| 2720 | /// | |
| 2721 | /// # Matching on unions | |
| 2722 | /// | |
| 2723 | /// It is possible to use pattern matching on `union`s. A single field name must | |
| 2724 | /// be used and it must match the name of one of the `union`'s field. | |
| 2725 | /// Like reading from a `union`, pattern matching on a `union` requires `unsafe`. | |
| 2726 | /// | |
| 2727 | /// ```rust | |
| 2728 | /// union IntOrFloat { | |
| 2729 | /// i: u32, | |
| 2730 | /// f: f32, | |
| 2731 | /// } | |
| 2732 | /// | |
| 2733 | /// let u = IntOrFloat { f: 1.0 }; | |
| 2734 | /// | |
| 2735 | /// unsafe { | |
| 2736 | /// match u { | |
| 2737 | /// IntOrFloat { i: 10 } => println!("Found exactly ten!"), | |
| 2738 | /// // Matching the field `f` provides an `f32`. | |
| 2739 | /// IntOrFloat { f } => println!("Found f = {f} !"), | |
| 2740 | /// } | |
| 2741 | /// } | |
| 2742 | /// ``` | |
| 2743 | /// | |
| 2744 | /// # References to union fields | |
| 2745 | /// | |
| 2746 | /// All fields in a `union` are all at the same place in memory which means | |
| 2747 | /// borrowing one borrows the entire `union`, for the same lifetime: | |
| 2748 | /// | |
| 2749 | /// ```rust,compile_fail,E0502 | |
| 2750 | /// union IntOrFloat { | |
| 2751 | /// i: u32, | |
| 2752 | /// f: f32, | |
| 2753 | /// } | |
| 2754 | /// | |
| 2755 | /// let mut u = IntOrFloat { f: 1.0 }; | |
| 2756 | /// | |
| 2757 | /// let f = unsafe { &u.f }; | |
| 2758 | /// // This will not compile because the field has already been borrowed, even | |
| 2759 | /// // if only immutably | |
| 2760 | /// let i = unsafe { &mut u.i }; | |
| 2761 | /// | |
| 2762 | /// *i = 10; | |
| 2763 | /// println!("f = {f} and i = {i}"); | |
| 2764 | /// ``` | |
| 2765 | /// | |
| 2766 | /// See the [Reference][union] for more information on `union`s. | |
| 2767 | /// | |
| 2768 | /// [`struct`]: keyword.struct.html | |
| 2769 | /// [union]: ../reference/items/unions.html | |
| 2770 | mod union_keyword {} |
library/std/src/lib.rs+12-9| ... | ... | @@ -772,20 +772,23 @@ pub mod from { |
| 772 | 772 | pub use core::from::From; |
| 773 | 773 | } |
| 774 | 774 | |
| 775 | // Include a number of private modules that exist solely to provide | |
| 776 | // the rustdoc documentation for primitive types. Using `include!` | |
| 777 | // because rustdoc only looks for these modules at the crate level. | |
| 778 | include!("../../core/src/primitive_docs.rs"); | |
| 775 | // We include the following files here *again* (they are already included in libcore) | |
| 776 | // so that they show up in search results for the std crate, and to avoid breaking | |
| 777 | // existing links: | |
| 778 | ||
| 779 | // documentation for built-in attributes. Using `include!` because rustdoc | |
| 780 | // only looks for these modules at the crate level. | |
| 781 | include!("../../core/src/attribute_docs.rs"); | |
| 779 | 782 | |
| 780 | 783 | // Include a number of private modules that exist solely to provide |
| 781 | 784 | // the rustdoc documentation for the existing keywords. Using `include!` |
| 782 | 785 | // because rustdoc only looks for these modules at the crate level. |
| 783 | include!("keyword_docs.rs"); | |
| 786 | include!("../../core/src/keyword_docs.rs"); | |
| 784 | 787 | |
| 785 | // Include private modules that exist solely to provide rustdoc | |
| 786 | // documentation for built-in attributes. Using `include!` because rustdoc | |
| 787 | // only looks for these modules at the crate level. | |
| 788 | include!("attribute_docs.rs"); | |
| 788 | // Include a number of private modules that exist solely to provide | |
| 789 | // the rustdoc documentation for primitive types. Using `include!` | |
| 790 | // because rustdoc only looks for these modules at the crate level. | |
| 791 | include!("../../core/src/primitive_docs.rs"); | |
| 789 | 792 | |
| 790 | 793 | // This is required to avoid an unstable error when `restricted-std` is not |
| 791 | 794 | // enabled. The use of #![feature(restricted_std)] in rustc-std-workspace-std |
src/bootstrap/src/core/builder/cargo.rs+29-10| ... | ... | @@ -14,8 +14,11 @@ use crate::{ |
| 14 | 14 | RemapScheme, TargetSelection, command, prepare_behaviour_dump_dir, t, |
| 15 | 15 | }; |
| 16 | 16 | |
| 17 | /// Represents flag values in `String` form with whitespace delimiter to pass it to the compiler | |
| 18 | /// later. | |
| 17 | /// Represents flag values in `String` form with a `\x1f` delimiter to pass to the compiler later. | |
| 18 | /// | |
| 19 | /// Flags are emitted via `CARGO_ENCODED_RUSTFLAGS` / `CARGO_ENCODED_RUSTDOCFLAGS`, | |
| 20 | /// which use `\x1f` (ASCII Unit Separator) as the delimiter and therefore allow spaces | |
| 21 | /// within individual flag values (e.g. paths from `llvm-config --libdir`). | |
| 19 | 22 | /// |
| 20 | 23 | /// `-Z crate-attr` flags will be applied recursively on the target code using the |
| 21 | 24 | /// `rustc_parse::parser::Parser`. See `rustc_builtin_macros::cmdline_attrs::inject` for more |
| ... | ... | @@ -51,11 +54,16 @@ impl Rustflags { |
| 51 | 54 | } |
| 52 | 55 | |
| 53 | 56 | fn arg(&mut self, arg: &str) -> &mut Self { |
| 54 | assert_eq!(arg.split(' ').count(), 1); | |
| 55 | if !self.0.is_empty() { | |
| 56 | self.0.push(' '); | |
| 57 | assert!( | |
| 58 | !arg.contains('\x1f'), | |
| 59 | "rustflag must not contain the ASCII unit separator (\\x1f): {arg:?}" | |
| 60 | ); | |
| 61 | if !arg.is_empty() { | |
| 62 | if !self.0.is_empty() { | |
| 63 | self.0.push('\x1f'); | |
| 64 | } | |
| 65 | self.0.push_str(arg); | |
| 57 | 66 | } |
| 58 | self.0.push_str(arg); | |
| 59 | 67 | self |
| 60 | 68 | } |
| 61 | 69 | |
| ... | ... | @@ -457,14 +465,21 @@ impl From<Cargo> for BootstrapCommand { |
| 457 | 465 | |
| 458 | 466 | cargo.command.args(cargo.args); |
| 459 | 467 | |
| 468 | // Always unset the plain RUSTFLAGS/RUSTDOCFLAGS so that downstream | |
| 469 | // tools (e.g. build.rs scripts) see only the encoded form. Any flags | |
| 470 | // from the caller's environment have already been folded into the | |
| 471 | // Rustflags struct via `propagate_cargo_env`. | |
| 472 | cargo.command.env_remove("RUSTFLAGS"); | |
| 473 | cargo.command.env_remove("RUSTDOCFLAGS"); | |
| 474 | ||
| 460 | 475 | let rustflags = &cargo.rustflags.0; |
| 461 | 476 | if !rustflags.is_empty() { |
| 462 | cargo.command.env("RUSTFLAGS", rustflags); | |
| 477 | cargo.command.env("CARGO_ENCODED_RUSTFLAGS", rustflags); | |
| 463 | 478 | } |
| 464 | 479 | |
| 465 | 480 | let rustdocflags = &cargo.rustdocflags.0; |
| 466 | 481 | if !rustdocflags.is_empty() { |
| 467 | cargo.command.env("RUSTDOCFLAGS", rustdocflags); | |
| 482 | cargo.command.env("CARGO_ENCODED_RUSTDOCFLAGS", rustdocflags); | |
| 468 | 483 | } |
| 469 | 484 | |
| 470 | 485 | let encoded_hostflags = cargo.hostflags.encode(); |
| ... | ... | @@ -918,7 +933,10 @@ impl Builder<'_> { |
| 918 | 933 | } |
| 919 | 934 | |
| 920 | 935 | let rustdoc_path = match cmd_kind { |
| 921 | Kind::Doc | Kind::Test | Kind::MiriTest => self.rustdoc_for_compiler(compiler), | |
| 936 | Kind::Doc => self.rustdoc_for_compiler(compiler), | |
| 937 | Kind::Test | Kind::MiriTest if self.test_target.runs_doctests() => { | |
| 938 | self.rustdoc_for_compiler(compiler) | |
| 939 | } | |
| 922 | 940 | _ => PathBuf::from("/path/to/nowhere/rustdoc/not/required"), |
| 923 | 941 | }; |
| 924 | 942 | |
| ... | ... | @@ -1183,8 +1201,9 @@ impl Builder<'_> { |
| 1183 | 1201 | if (mode == Mode::ToolRustcPrivate || mode == Mode::Codegen) |
| 1184 | 1202 | && let Some(llvm_config) = self.llvm_config(target) |
| 1185 | 1203 | { |
| 1186 | let llvm_libdir = | |
| 1204 | let llvm_libdir_raw = | |
| 1187 | 1205 | command(llvm_config).cached().arg("--libdir").run_capture_stdout(self).stdout(); |
| 1206 | let llvm_libdir = llvm_libdir_raw.trim(); | |
| 1188 | 1207 | if target.is_msvc() { |
| 1189 | 1208 | rustflags.arg(&format!("-Clink-arg=-LIBPATH:{llvm_libdir}")); |
| 1190 | 1209 | } else { |
src/bootstrap/src/core/builder/mod.rs+11-1| ... | ... | @@ -1150,6 +1150,7 @@ impl<'a> Builder<'a> { |
| 1150 | 1150 | /// compiler will run on, *not* the target it will build code for). Explicitly does not take |
| 1151 | 1151 | /// `Compiler` since all `Compiler` instances are meant to be obtained through this function, |
| 1152 | 1152 | /// since it ensures that they are valid (i.e., built and assembled). |
| 1153 | #[track_caller] | |
| 1153 | 1154 | #[cfg_attr( |
| 1154 | 1155 | feature = "tracing", |
| 1155 | 1156 | instrument( |
| ... | ... | @@ -1183,6 +1184,7 @@ impl<'a> Builder<'a> { |
| 1183 | 1184 | /// |
| 1184 | 1185 | /// However, without this optimization, we would also build stage 2 rustc for **target1**, |
| 1185 | 1186 | /// which is completely wasteful. |
| 1187 | #[track_caller] | |
| 1186 | 1188 | pub fn compiler_for_std(&self, stage: u32) -> Compiler { |
| 1187 | 1189 | if compile::Std::should_be_uplifted_from_stage_1(self, stage) { |
| 1188 | 1190 | self.compiler(1, self.host_target) |
| ... | ... | @@ -1202,6 +1204,7 @@ impl<'a> Builder<'a> { |
| 1202 | 1204 | /// sysroot. |
| 1203 | 1205 | /// |
| 1204 | 1206 | /// See `force_use_stage1` and `force_use_stage2` for documentation on what each argument is. |
| 1207 | #[track_caller] | |
| 1205 | 1208 | #[cfg_attr( |
| 1206 | 1209 | feature = "tracing", |
| 1207 | 1210 | instrument( |
| ... | ... | @@ -1249,6 +1252,7 @@ impl<'a> Builder<'a> { |
| 1249 | 1252 | /// Prefer using this method rather than manually invoking `Std::new`. |
| 1250 | 1253 | /// |
| 1251 | 1254 | /// Returns an optional build stamp, if libstd was indeed built. |
| 1255 | #[track_caller] | |
| 1252 | 1256 | #[cfg_attr( |
| 1253 | 1257 | feature = "tracing", |
| 1254 | 1258 | instrument( |
| ... | ... | @@ -1297,17 +1301,20 @@ Alternatively, you can set `build.local-rebuild=true` and use a stage0 compiler |
| 1297 | 1301 | } |
| 1298 | 1302 | } |
| 1299 | 1303 | |
| 1304 | #[track_caller] | |
| 1300 | 1305 | pub fn sysroot(&self, compiler: Compiler) -> PathBuf { |
| 1301 | 1306 | self.ensure(compile::Sysroot::new(compiler)) |
| 1302 | 1307 | } |
| 1303 | 1308 | |
| 1304 | 1309 | /// Returns the bindir for a compiler's sysroot. |
| 1310 | #[track_caller] | |
| 1305 | 1311 | pub fn sysroot_target_bindir(&self, compiler: Compiler, target: TargetSelection) -> PathBuf { |
| 1306 | 1312 | self.ensure(Libdir { compiler, target }).join(target).join("bin") |
| 1307 | 1313 | } |
| 1308 | 1314 | |
| 1309 | 1315 | /// Returns the libdir where the standard library and other artifacts are |
| 1310 | 1316 | /// found for a compiler's sysroot. |
| 1317 | #[track_caller] | |
| 1311 | 1318 | pub fn sysroot_target_libdir(&self, compiler: Compiler, target: TargetSelection) -> PathBuf { |
| 1312 | 1319 | self.ensure(Libdir { compiler, target }).join(target).join("lib") |
| 1313 | 1320 | } |
| ... | ... | @@ -1416,6 +1423,7 @@ Alternatively, you can set `build.local-rebuild=true` and use a stage0 compiler |
| 1416 | 1423 | /// Returns a path to `Rustdoc` that "belongs" to the `target_compiler`. |
| 1417 | 1424 | /// It can be either a stage0 rustdoc or a locally built rustdoc that *links* to |
| 1418 | 1425 | /// `target_compiler`. |
| 1426 | #[track_caller] | |
| 1419 | 1427 | pub fn rustdoc_for_compiler(&self, target_compiler: Compiler) -> PathBuf { |
| 1420 | 1428 | self.ensure(tool::Rustdoc { target_compiler }) |
| 1421 | 1429 | } |
| ... | ... | @@ -1532,6 +1540,7 @@ Alternatively, you can set `build.local-rebuild=true` and use a stage0 compiler |
| 1532 | 1540 | /// Ensure that a given step is built, returning its output. This will |
| 1533 | 1541 | /// cache the step, so it is safe (and good!) to call this as often as |
| 1534 | 1542 | /// needed to ensure that all dependencies are built. |
| 1543 | #[track_caller] | |
| 1535 | 1544 | pub fn ensure<S: Step>(&'a self, step: S) -> S::Output { |
| 1536 | 1545 | { |
| 1537 | 1546 | let mut stack = self.stack.borrow_mut(); |
| ... | ... | @@ -1589,7 +1598,8 @@ Alternatively, you can set `build.local-rebuild=true` and use a stage0 compiler |
| 1589 | 1598 | // in the step_name field. |
| 1590 | 1599 | "step", |
| 1591 | 1600 | step_name = pretty_step_name::<S>(), |
| 1592 | args = step_debug_args(&step) | |
| 1601 | args = step_debug_args(&step), | |
| 1602 | location = crate::utils::tracing::format_location(*std::panic::Location::caller()) | |
| 1593 | 1603 | ); |
| 1594 | 1604 | span.entered() |
| 1595 | 1605 | }; |
src/bootstrap/src/core/builder/tests.rs+13| ... | ... | @@ -2423,6 +2423,19 @@ mod snapshot { |
| 2423 | 2423 | } |
| 2424 | 2424 | } |
| 2425 | 2425 | |
| 2426 | #[test] | |
| 2427 | fn test_library_tests_only_does_not_build_rustdoc() { | |
| 2428 | let ctx = TestCtx::new(); | |
| 2429 | let host = TargetSelection::from_user(&host_target()); | |
| 2430 | insta::assert_snapshot!( | |
| 2431 | ctx.config("test").args(&["--tests", "library/core"]).render_steps(), | |
| 2432 | @r" | |
| 2433 | [build] llvm <host> | |
| 2434 | [build] rustc 0 <host> -> rustc 1 <host> | |
| 2435 | [build] rustc 1 <host> -> std 1 <host> | |
| 2436 | "); | |
| 2437 | } | |
| 2438 | ||
| 2426 | 2439 | #[test] |
| 2427 | 2440 | fn test_cargo_stage_1() { |
| 2428 | 2441 | let ctx = TestCtx::new(); |
src/bootstrap/src/utils/step_graph.rs+42-17| ... | ... | @@ -1,10 +1,12 @@ |
| 1 | use std::collections::{HashMap, HashSet}; | |
| 1 | use std::collections::HashMap; | |
| 2 | 2 | use std::fmt::Debug; |
| 3 | 3 | use std::io::BufWriter; |
| 4 | use std::panic::Location; | |
| 4 | 5 | use std::path::Path; |
| 5 | 6 | |
| 6 | 7 | use crate::core::builder::{AnyDebug, Step, pretty_step_name}; |
| 7 | 8 | use crate::t; |
| 9 | use crate::utils::tracing::format_location; | |
| 8 | 10 | |
| 9 | 11 | /// Records the executed steps and their dependencies in a directed graph, |
| 10 | 12 | /// which can then be rendered into a DOT file for visualization. |
| ... | ... | @@ -20,6 +22,7 @@ pub struct StepGraph { |
| 20 | 22 | } |
| 21 | 23 | |
| 22 | 24 | impl StepGraph { |
| 25 | #[track_caller] | |
| 23 | 26 | pub fn register_step_execution<S: Step>( |
| 24 | 27 | &mut self, |
| 25 | 28 | step: &S, |
| ... | ... | @@ -57,6 +60,7 @@ impl StepGraph { |
| 57 | 60 | } |
| 58 | 61 | } |
| 59 | 62 | |
| 63 | #[track_caller] | |
| 60 | 64 | pub fn register_cached_step<S: Step>( |
| 61 | 65 | &mut self, |
| 62 | 66 | step: &S, |
| ... | ... | @@ -97,12 +101,18 @@ struct Node { |
| 97 | 101 | struct NodeHandle(usize); |
| 98 | 102 | |
| 99 | 103 | /// Represents a dependency between two bootstrap steps. |
| 100 | #[derive(PartialEq, Eq, Hash, PartialOrd, Ord)] | |
| 101 | struct Edge { | |
| 102 | src: NodeHandle, | |
| 103 | dst: NodeHandle, | |
| 104 | #[derive(Default)] | |
| 105 | struct EdgeData { | |
| 104 | 106 | // Was the corresponding execution of a step cached, or was the step actually executed? |
| 105 | 107 | cached: bool, |
| 108 | // Locations from where the step was called | |
| 109 | locations: Vec<Location<'static>>, | |
| 110 | } | |
| 111 | ||
| 112 | #[derive(PartialEq, Eq, Hash, PartialOrd, Ord, Copy, Clone)] | |
| 113 | struct EdgeKey { | |
| 114 | src: NodeHandle, | |
| 115 | dst: NodeHandle, | |
| 106 | 116 | } |
| 107 | 117 | |
| 108 | 118 | // We could use a library for this, but they either: |
| ... | ... | @@ -114,8 +124,8 @@ struct Edge { |
| 114 | 124 | #[derive(Default)] |
| 115 | 125 | struct DotGraph { |
| 116 | 126 | nodes: Vec<Node>, |
| 127 | edges: HashMap<EdgeKey, EdgeData>, | |
| 117 | 128 | /// The `NodeHandle` represents an index within `self.nodes` |
| 118 | edges: HashSet<Edge>, | |
| 119 | 129 | key_to_index: HashMap<String, NodeHandle>, |
| 120 | 130 | } |
| 121 | 131 | |
| ... | ... | @@ -127,16 +137,19 @@ impl DotGraph { |
| 127 | 137 | handle |
| 128 | 138 | } |
| 129 | 139 | |
| 140 | #[track_caller] | |
| 130 | 141 | fn add_edge(&mut self, src: NodeHandle, dst: NodeHandle) { |
| 131 | self.edges.insert(Edge { src, dst, cached: false }); | |
| 142 | let key = EdgeKey { src, dst }; | |
| 143 | let edge = self.edges.entry(key).or_default(); | |
| 144 | edge.locations.push(*Location::caller()); | |
| 132 | 145 | } |
| 133 | 146 | |
| 147 | #[track_caller] | |
| 134 | 148 | fn add_cached_edge(&mut self, src: NodeHandle, dst: NodeHandle) { |
| 135 | // There's no point in rendering both cached and uncached edge | |
| 136 | let uncached = Edge { src, dst, cached: false }; | |
| 137 | if !self.edges.contains(&uncached) { | |
| 138 | self.edges.insert(Edge { src, dst, cached: true }); | |
| 139 | } | |
| 149 | let key = EdgeKey { src, dst }; | |
| 150 | let edge = self.edges.entry(key).or_default(); | |
| 151 | edge.cached = true; | |
| 152 | edge.locations.push(*Location::caller()); | |
| 140 | 153 | } |
| 141 | 154 | |
| 142 | 155 | fn get_handle_by_key(&self, key: &str) -> Option<NodeHandle> { |
| ... | ... | @@ -157,11 +170,23 @@ impl DotGraph { |
| 157 | 170 | )?; |
| 158 | 171 | } |
| 159 | 172 | |
| 160 | let mut edges: Vec<&Edge> = self.edges.iter().collect(); | |
| 161 | edges.sort(); | |
| 162 | for edge in edges { | |
| 163 | let style = if edge.cached { "dashed" } else { "solid" }; | |
| 164 | writeln!(file, r#"{} -> {} [style="{style}"]"#, edge.src.0, edge.dst.0)?; | |
| 173 | let mut edges: Vec<(&EdgeKey, &EdgeData)> = self.edges.iter().collect(); | |
| 174 | edges.sort_by_key(|(key, _)| **key); | |
| 175 | for (key, data) in edges { | |
| 176 | let style = if data.cached { "dashed" } else { "solid" }; | |
| 177 | let mut locations = data | |
| 178 | .locations | |
| 179 | .iter() | |
| 180 | .map(|location| format_location(*location)) | |
| 181 | .collect::<Vec<_>>(); | |
| 182 | locations.sort(); | |
| 183 | locations.dedup(); | |
| 184 | let locations = locations.join(", "); | |
| 185 | writeln!( | |
| 186 | file, | |
| 187 | r#"{} -> {} [style="{style}", tooltip="{locations}"]"#, | |
| 188 | key.src.0, key.dst.0, | |
| 189 | )?; | |
| 165 | 190 | } |
| 166 | 191 | |
| 167 | 192 | writeln!(file, "}}") |
src/bootstrap/src/utils/tracing.rs+1-1| ... | ... | @@ -351,7 +351,7 @@ mod inner { |
| 351 | 351 | let field = &values.fields[0]; |
| 352 | 352 | write!(writer, " {{{}}}", field.1)?; |
| 353 | 353 | } |
| 354 | write_location(writer, span.metadata())?; | |
| 354 | write_with_location(writer)?; | |
| 355 | 355 | } |
| 356 | 356 | // Executed command |
| 357 | 357 | COMMAND_SPAN_TARGET => { |
src/doc/unstable-book/src/compiler-flags/patchable-function-entry.md+6-3| ... | ... | @@ -2,10 +2,13 @@ |
| 2 | 2 | |
| 3 | 3 | -------------------- |
| 4 | 4 | |
| 5 | The `-Z patchable-function-entry=total_nops,prefix_nops` or `-Z patchable-function-entry=total_nops` | |
| 5 | The `-Z patchable-function-entry=total_nops,prefix_nops,record_section`, | |
| 6 | `-Z patchable-function-entry=total_nops,prefix_nops`, or | |
| 7 | `-Z patchable-function-entry=total_nops` | |
| 6 | 8 | compiler flag enables nop padding of function entries with 'total_nops' nops, with |
| 7 | an offset for the entry of the function at 'prefix_nops' nops. In the second form, | |
| 8 | 'prefix_nops' defaults to 0. | |
| 9 | an offset for the entry of the function at 'prefix_nops' nops. In the third form, | |
| 10 | 'prefix_nops' defaults to 0. record\_section can specify a specific linker section | |
| 11 | to place entry record in, the default is `__patchable_function_entries`. | |
| 9 | 12 | |
| 10 | 13 | As an illustrative example, `-Z patchable-function-entry=3,2` would produce: |
| 11 | 14 |
src/tools/miri/tests/ui.rs+2-1| ... | ... | @@ -182,8 +182,9 @@ fn miri_config( |
| 182 | 182 | .map(Into::into) |
| 183 | 183 | .collect(), |
| 184 | 184 | envs: vec![ |
| 185 | // Reset `RUSTFLAGS` to work around <https://github.com/rust-lang/rust/pull/119574#issuecomment-1876878344>. | |
| 185 | // Reset `RUSTFLAGS`/`CARGO_ENCODED_RUSTFLAGS` to work around <https://github.com/rust-lang/rust/pull/119574#issuecomment-1876878344>. | |
| 186 | 186 | ("RUSTFLAGS".into(), None), |
| 187 | ("CARGO_ENCODED_RUSTFLAGS".into(), None), | |
| 187 | 188 | // Reset `MIRIFLAGS` because it caused trouble in the past and should not be needed. |
| 188 | 189 | ("MIRIFLAGS".into(), None), |
| 189 | 190 | // Allow `cargo miri build`. |
tests/codegen-llvm/patchable-function-entry/patchable-function-entry-both-flags.rs+32| ... | ... | @@ -39,6 +39,26 @@ pub fn fun5() {} |
| 39 | 39 | #[patchable_function_entry(prefix_nops = 4)] |
| 40 | 40 | pub fn fun6() {} |
| 41 | 41 | |
| 42 | // The attribute should override patchable-function-prefix to 4 | |
| 43 | // and patchable-function-entry to the default of 0, clearing it entirely, | |
| 44 | // while setting patchable-function-entry-section. | |
| 45 | #[no_mangle] | |
| 46 | #[patchable_function_entry(prefix_nops = 4, section = "foo")] | |
| 47 | pub fn fun7() {} | |
| 48 | ||
| 49 | // The attribute should override patchable-function-entry-section, | |
| 50 | // while passing through the commandline options. | |
| 51 | #[no_mangle] | |
| 52 | #[patchable_function_entry(section = "bar")] | |
| 53 | pub fn fun8() {} | |
| 54 | ||
| 55 | // The attribute should override patchable-function-entry to 5 | |
| 56 | // and patchable-function-prefix to the default of 0, clearing it entirely, | |
| 57 | // while setting patchable-function-entry-section. | |
| 58 | #[no_mangle] | |
| 59 | #[patchable_function_entry(entry_nops = 5, section = "baz")] | |
| 60 | pub fn fun9() {} | |
| 61 | ||
| 42 | 62 | // CHECK: @fun0() unnamed_addr #0 |
| 43 | 63 | // CHECK: @fun1() unnamed_addr #1 |
| 44 | 64 | // CHECK: @fun2() unnamed_addr #2 |
| ... | ... | @@ -46,6 +66,9 @@ pub fn fun6() {} |
| 46 | 66 | // CHECK: @fun4() unnamed_addr #4 |
| 47 | 67 | // CHECK: @fun5() unnamed_addr #5 |
| 48 | 68 | // CHECK: @fun6() unnamed_addr #6 |
| 69 | // CHECK: @fun7() unnamed_addr #7 | |
| 70 | // CHECK: @fun8() unnamed_addr #8 | |
| 71 | // CHECK: @fun9() unnamed_addr #9 | |
| 49 | 72 | |
| 50 | 73 | // CHECK: attributes #0 = { {{.*}}"patchable-function-entry"="5"{{.*}}"patchable-function-prefix"="10" {{.*}} } |
| 51 | 74 | // CHECK: attributes #1 = { {{.*}}"patchable-function-entry"="2"{{.*}}"patchable-function-prefix"="1" {{.*}} } |
| ... | ... | @@ -62,3 +85,12 @@ pub fn fun6() {} |
| 62 | 85 | |
| 63 | 86 | // CHECK: attributes #6 = { {{.*}}"patchable-function-prefix"="4"{{.*}} } |
| 64 | 87 | // CHECK-NOT: attributes #6 = { {{.*}}patchable-function-entry{{.*}} } |
| 88 | // | |
| 89 | // CHECK: attributes #7 = { {{.*}}"patchable-function-entry-section"="foo"{{.*}}"patchable-function-prefix"="4" {{.*}} } | |
| 90 | // CHECK-NOT: attributes #7 = { {{.*}}"patchable-function-entry"{{.*}} } | |
| 91 | // | |
| 92 | // CHECK: attributes #8 = { {{.*}}"patchable-function-entry-section"="bar"{{.*}} } | |
| 93 | // CHECK-NOT: attributes #8 = { {{.*}}"patchable-function-entry"{{.*}} } | |
| 94 | // | |
| 95 | // CHECK: attributes #9 = { {{.*}}"patchable-function-entry"="5"{{.*}}"patchable-function-entry-section"="baz" {{.*}} } | |
| 96 | // CHECK-NOT: attributes #9 = { {{.*}}"patchable-function-prefix{{.*}} } |
tests/codegen-llvm/patchable-function-entry/patchable-function-entry-section.rs created+20| ... | ... | @@ -0,0 +1,20 @@ |
| 1 | //@ compile-flags: -Z patchable-function-entry=15,10,default_foo_section | |
| 2 | // | |
| 3 | ||
| 4 | #![feature(patchable_function_entry)] | |
| 5 | #![crate_type = "lib"] | |
| 6 | ||
| 7 | // This should have the default, as set by the compile flags | |
| 8 | #[no_mangle] | |
| 9 | pub fn fun0() {} | |
| 10 | ||
| 11 | // This should override the default section name | |
| 12 | #[no_mangle] | |
| 13 | #[patchable_function_entry(section = "bar_section")] | |
| 14 | pub fn fun1() {} | |
| 15 | ||
| 16 | // CHECK: @fun0() unnamed_addr #0 | |
| 17 | // CHECK: @fun1() unnamed_addr #1 | |
| 18 | ||
| 19 | // CHECK: attributes #0 = { {{.*}}"patchable-function-entry"="5"{{.*}}"patchable-function-entry-section"="default_foo_section"{{.*}}"patchable-function-prefix"="10" {{.*}} } | |
| 20 | // CHECK: attributes #1 = { {{.*}}"patchable-function-entry"="5"{{.*}}"patchable-function-entry-section"="bar_section"{{.*}}"patchable-function-prefix"="10" {{.*}} } |
tests/ui/attributes/malformed-attrs.stderr+2-2| ... | ... | @@ -550,8 +550,8 @@ LL | #[patchable_function_entry] |
| 550 | 550 | | |
| 551 | 551 | help: must be of the form |
| 552 | 552 | | |
| 553 | LL | #[patchable_function_entry(prefix_nops = m, entry_nops = n)] | |
| 554 | | +++++++++++++++++++++++++++++++++ | |
| 553 | LL | #[patchable_function_entry(prefix_nops = m, entry_nops = n, section = "section")] | |
| 554 | | ++++++++++++++++++++++++++++++++++++++++++++++++++++++ | |
| 555 | 555 | |
| 556 | 556 | error[E0565]: malformed `coroutine` attribute input |
| 557 | 557 | --> $DIR/malformed-attrs.rs:118:5 |
tests/ui/lint/unused-parens-trailing-space-issue-158583.rs created+5| ... | ... | @@ -0,0 +1,5 @@ |
| 1 | fn main() { | |
| 2 | #[deny(unused_parens)] | |
| 3 | let _x = (3 + 6); | |
| 4 | //~^ ERROR unnecessary parentheses around assigned value | |
| 5 | } |
tests/ui/lint/unused-parens-trailing-space-issue-158583.stderr created+19| ... | ... | @@ -0,0 +1,19 @@ |
| 1 | error: unnecessary parentheses around assigned value | |
| 2 | --> $DIR/unused-parens-trailing-space-issue-158583.rs:3:14 | |
| 3 | | | |
| 4 | LL | let _x = (3 + 6); | |
| 5 | | ^ ^ | |
| 6 | | | |
| 7 | note: the lint level is defined here | |
| 8 | --> $DIR/unused-parens-trailing-space-issue-158583.rs:2:12 | |
| 9 | | | |
| 10 | LL | #[deny(unused_parens)] | |
| 11 | | ^^^^^^^^^^^^^ | |
| 12 | help: remove these parentheses | |
| 13 | | | |
| 14 | LL - let _x = (3 + 6); | |
| 15 | LL + let _x = 3 + 6; | |
| 16 | | | |
| 17 | ||
| 18 | error: aborting due to 1 previous error | |
| 19 |
tests/ui/patchable-function-entry/patchable-function-entry-attribute.rs+16| ... | ... | @@ -24,3 +24,19 @@ pub fn no_parameters_given() {} |
| 24 | 24 | #[patchable_function_entry(prefix_nops = 255, prefix_nops = 255)] |
| 25 | 25 | //~^ ERROR malformed |
| 26 | 26 | pub fn duplicate_parameter() {} |
| 27 | ||
| 28 | #[patchable_function_entry(section = 255)] | |
| 29 | //~^ ERROR malformed | |
| 30 | pub fn invalid_section_parameter() {} | |
| 31 | ||
| 32 | #[patchable_function_entry(section = "foo", section = "bar")] | |
| 33 | //~^ ERROR malformed | |
| 34 | pub fn duplicate_section_parameter() {} | |
| 35 | ||
| 36 | #[patchable_function_entry(section = "fo\0o")] | |
| 37 | //~^ ERROR null characters | |
| 38 | pub fn nul_in_section_parameter() {} | |
| 39 | ||
| 40 | #[patchable_function_entry(section = "")] | |
| 41 | //~^ ERROR empty | |
| 42 | pub fn empty_section_parameter() {} |
tests/ui/patchable-function-entry/patchable-function-entry-attribute.stderr+50-10| ... | ... | @@ -9,7 +9,7 @@ LL | #[patchable_function_entry(prefix_nops = 256, entry_nops = 0)] |
| 9 | 9 | help: must be of the form |
| 10 | 10 | | |
| 11 | 11 | LL - #[patchable_function_entry(prefix_nops = 256, entry_nops = 0)] |
| 12 | LL + #[patchable_function_entry(prefix_nops = m, entry_nops = n)] | |
| 12 | LL + #[patchable_function_entry(prefix_nops = m, entry_nops = n, section = "section")] | |
| 13 | 13 | | |
| 14 | 14 | |
| 15 | 15 | error[E0539]: malformed `patchable_function_entry` attribute input |
| ... | ... | @@ -23,7 +23,7 @@ LL | #[patchable_function_entry(prefix_nops = "stringvalue", entry_nops = 0)] |
| 23 | 23 | help: must be of the form |
| 24 | 24 | | |
| 25 | 25 | LL - #[patchable_function_entry(prefix_nops = "stringvalue", entry_nops = 0)] |
| 26 | LL + #[patchable_function_entry(prefix_nops = m, entry_nops = n)] | |
| 26 | LL + #[patchable_function_entry(prefix_nops = m, entry_nops = n, section = "section")] | |
| 27 | 27 | | |
| 28 | 28 | |
| 29 | 29 | error[E0539]: malformed `patchable_function_entry` attribute input |
| ... | ... | @@ -34,8 +34,8 @@ LL | #[patchable_function_entry] |
| 34 | 34 | | |
| 35 | 35 | help: must be of the form |
| 36 | 36 | | |
| 37 | LL | #[patchable_function_entry(prefix_nops = m, entry_nops = n)] | |
| 38 | | +++++++++++++++++++++++++++++++++ | |
| 37 | LL | #[patchable_function_entry(prefix_nops = m, entry_nops = n, section = "section")] | |
| 38 | | ++++++++++++++++++++++++++++++++++++++++++++++++++++++ | |
| 39 | 39 | |
| 40 | 40 | error[E0539]: malformed `patchable_function_entry` attribute input |
| 41 | 41 | --> $DIR/patchable-function-entry-attribute.rs:16:1 |
| ... | ... | @@ -48,7 +48,7 @@ LL | #[patchable_function_entry(prefix_nops = 10, something = 0)] |
| 48 | 48 | help: must be of the form |
| 49 | 49 | | |
| 50 | 50 | LL - #[patchable_function_entry(prefix_nops = 10, something = 0)] |
| 51 | LL + #[patchable_function_entry(prefix_nops = m, entry_nops = n)] | |
| 51 | LL + #[patchable_function_entry(prefix_nops = m, entry_nops = n, section = "section")] | |
| 52 | 52 | | |
| 53 | 53 | |
| 54 | 54 | error[E0539]: malformed `patchable_function_entry` attribute input |
| ... | ... | @@ -61,8 +61,8 @@ LL | #[patchable_function_entry()] |
| 61 | 61 | | |
| 62 | 62 | help: must be of the form |
| 63 | 63 | | |
| 64 | LL | #[patchable_function_entry(prefix_nops = m, entry_nops = n)] | |
| 65 | | +++++++++++++++++++++++++++++++ | |
| 64 | LL | #[patchable_function_entry(prefix_nops = m, entry_nops = n, section = "section")] | |
| 65 | | ++++++++++++++++++++++++++++++++++++++++++++++++++++ | |
| 66 | 66 | |
| 67 | 67 | error[E0538]: malformed `patchable_function_entry` attribute input |
| 68 | 68 | --> $DIR/patchable-function-entry-attribute.rs:24:1 |
| ... | ... | @@ -75,10 +75,50 @@ LL | #[patchable_function_entry(prefix_nops = 255, prefix_nops = 255)] |
| 75 | 75 | help: must be of the form |
| 76 | 76 | | |
| 77 | 77 | LL - #[patchable_function_entry(prefix_nops = 255, prefix_nops = 255)] |
| 78 | LL + #[patchable_function_entry(prefix_nops = m, entry_nops = n)] | |
| 78 | LL + #[patchable_function_entry(prefix_nops = m, entry_nops = n, section = "section")] | |
| 79 | 79 | | |
| 80 | 80 | |
| 81 | error: aborting due to 6 previous errors | |
| 81 | error[E0539]: malformed `patchable_function_entry` attribute input | |
| 82 | --> $DIR/patchable-function-entry-attribute.rs:28:1 | |
| 83 | | | |
| 84 | LL | #[patchable_function_entry(section = 255)] | |
| 85 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---^^ | |
| 86 | | | | |
| 87 | | expected a string literal here | |
| 88 | | | |
| 89 | help: must be of the form | |
| 90 | | | |
| 91 | LL - #[patchable_function_entry(section = 255)] | |
| 92 | LL + #[patchable_function_entry(prefix_nops = m, entry_nops = n, section = "section")] | |
| 93 | | | |
| 94 | ||
| 95 | error[E0538]: malformed `patchable_function_entry` attribute input | |
| 96 | --> $DIR/patchable-function-entry-attribute.rs:32:1 | |
| 97 | | | |
| 98 | LL | #[patchable_function_entry(section = "foo", section = "bar")] | |
| 99 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-------^^^^^^^^^^ | |
| 100 | | | | |
| 101 | | found `section` used as a key more than once | |
| 102 | | | |
| 103 | help: must be of the form | |
| 104 | | | |
| 105 | LL - #[patchable_function_entry(section = "foo", section = "bar")] | |
| 106 | LL + #[patchable_function_entry(prefix_nops = m, entry_nops = n, section = "section")] | |
| 107 | | | |
| 108 | ||
| 109 | error[E0648]: `section` may not contain null characters | |
| 110 | --> $DIR/patchable-function-entry-attribute.rs:36:38 | |
| 111 | | | |
| 112 | LL | #[patchable_function_entry(section = "fo\0o")] | |
| 113 | | ^^^^^^^ | |
| 114 | ||
| 115 | error: `section` may not be empty | |
| 116 | --> $DIR/patchable-function-entry-attribute.rs:40:38 | |
| 117 | | | |
| 118 | LL | #[patchable_function_entry(section = "")] | |
| 119 | | ^^ | |
| 120 | ||
| 121 | error: aborting due to 10 previous errors | |
| 82 | 122 | |
| 83 | Some errors have detailed explanations: E0538, E0539. | |
| 123 | Some errors have detailed explanations: E0538, E0539, E0648. | |
| 84 | 124 | For more information about an error, try `rustc --explain E0538`. |
tests/ui/patchable-function-entry/patchable-function-entry-flags.stderr+1-1| ... | ... | @@ -1,2 +1,2 @@ |
| 1 | error: incorrect value `1,2` for unstable option `patchable-function-entry` - either two comma separated integers (total_nops,prefix_nops), with prefix_nops <= total_nops, or one integer (total_nops) was expected | |
| 1 | error: incorrect value `1,2` for unstable option `patchable-function-entry` - a comma separated list of (prefix_nops,total_nops,section_name), (prefix_nops,total_nops), or (total_nops). Where prefix_nops <= total_nops where 0 < total_nops <= 255 and prefix_nops <= total_nops was expected | |
| 2 | 2 |
tests/ui/proc-macro/auxiliary/nonfatal-parsing-body.rs+18-16| ... | ... | @@ -7,12 +7,14 @@ use proc_macro::*; |
| 7 | 7 | use self::Mode::*; |
| 8 | 8 | |
| 9 | 9 | // FIXME: all cases should become `NormalOk` or `NormalErr` |
| 10 | // | |
| 11 | // And .stderr should be empty (no diagnostics should get emitted from fallible parsing in the proc | |
| 12 | // macro). | |
| 10 | 13 | #[derive(PartialEq, Clone, Copy)] |
| 11 | 14 | enum Mode { |
| 12 | 15 | NormalOk, |
| 13 | 16 | NormalErr, |
| 14 | 17 | OtherError, |
| 15 | OtherWithPanic, | |
| 16 | 18 | } |
| 17 | 19 | |
| 18 | 20 | fn print_unspanned<T>(s: &str) -> Result<T, LexError> |
| ... | ... | @@ -43,12 +45,11 @@ where |
| 43 | 45 | assert!(t.is_err()); |
| 44 | 46 | } |
| 45 | 47 | OtherError => { |
| 46 | print_unspanned::<T>(s); | |
| 47 | } | |
| 48 | OtherWithPanic => { | |
| 49 | if catch_unwind(|| print_unspanned::<T>(s)).is_ok() { | |
| 50 | eprintln!("{s} did not panic"); | |
| 51 | } | |
| 48 | let t = print_unspanned::<T>(s); | |
| 49 | // For now we assert OK here, but in the future this should all move to NormalErr. | |
| 50 | // Any case that's failing this should go to NormalErr, probably after verifying that a | |
| 51 | // diagnostic did get emitted. | |
| 52 | assert!(t.is_ok()); | |
| 52 | 53 | } |
| 53 | 54 | } |
| 54 | 55 | } |
| ... | ... | @@ -136,9 +137,9 @@ pub fn run() { |
| 136 | 137 | // FIXME: all of the cases below should return an Err and emit no diagnostics, but don't yet. |
| 137 | 138 | |
| 138 | 139 | // emits diagnostics and returns LexError |
| 139 | lit("r'r'", OtherError); | |
| 140 | lit("c'r'", OtherError); | |
| 141 | lit("\u{2000}", OtherError); | |
| 140 | lit("r'r'", NormalErr); | |
| 141 | lit("c'r'", NormalErr); | |
| 142 | lit("\u{2000}", NormalErr); | |
| 142 | 143 | |
| 143 | 144 | // emits diagnostic and returns a seemingly valid tokenstream |
| 144 | 145 | stream("r'r'", OtherError); |
| ... | ... | @@ -146,8 +147,8 @@ pub fn run() { |
| 146 | 147 | stream("\u{2000}", OtherError); |
| 147 | 148 | |
| 148 | 149 | for parse in [stream as fn(&str, Mode), lit] { |
| 149 | // emits diagnostic(s), then panics | |
| 150 | parse("r#", OtherWithPanic); | |
| 150 | // emits diagnostic(s), then returns LexError | |
| 151 | parse("r#", NormalErr); | |
| 151 | 152 | |
| 152 | 153 | // emits diagnostic(s), then returns Ok(Literal { kind: ErrWithGuar, .. }) |
| 153 | 154 | parse("0b2", OtherError); |
| ... | ... | @@ -158,9 +159,10 @@ pub fn run() { |
| 158 | 159 | "' |
| 159 | 160 | '", OtherError, |
| 160 | 161 | ); |
| 161 | parse(&format!("r{0}\"a\"{0}", "#".repeat(256)), OtherWithPanic); | |
| 162 | ||
| 163 | // emits diagnostic, then, when parsing as a lit, returns LexError, otherwise ErrWithGuar | |
| 164 | parse("/*a*/ 0b2 //", OtherError); | |
| 162 | parse(&format!("r{0}\"a\"{0}", "#".repeat(256)), NormalErr); | |
| 165 | 163 | } |
| 164 | ||
| 165 | // emits diagnostic, then, when parsing as a lit, returns LexError, otherwise ErrWithGuar | |
| 166 | lit("/*a*/ 0b2 //", NormalErr); | |
| 167 | stream("/*a*/ 0b2 //", OtherError); | |
| 166 | 168 | } |
tests/ui/proc-macro/nonfatal-parsing.stderr+9-9| ... | ... | @@ -130,15 +130,6 @@ LL | nonfatal_parsing::run!(); |
| 130 | 130 | | |
| 131 | 131 | = note: this error originates in the macro `nonfatal_parsing::run` (in Nightly builds, run with -Z macro-backtrace for more info) |
| 132 | 132 | |
| 133 | error: invalid digit for a base 2 literal | |
| 134 | --> $DIR/nonfatal-parsing.rs:15:5 | |
| 135 | | | |
| 136 | LL | nonfatal_parsing::run!(); | |
| 137 | | ^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 138 | | | |
| 139 | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` | |
| 140 | = note: this error originates in the macro `nonfatal_parsing::run` (in Nightly builds, run with -Z macro-backtrace for more info) | |
| 141 | ||
| 142 | 133 | error: found invalid character; only `#` is allowed in raw string delimitation: \u{0} |
| 143 | 134 | --> <proc-macro source code>:1:1 |
| 144 | 135 | | |
| ... | ... | @@ -199,6 +190,15 @@ error: invalid digit for a base 2 literal |
| 199 | 190 | LL | /*a*/ 0b2 // |
| 200 | 191 | | ^ |
| 201 | 192 | |
| 193 | error: invalid digit for a base 2 literal | |
| 194 | --> $DIR/nonfatal-parsing.rs:15:5 | |
| 195 | | | |
| 196 | LL | nonfatal_parsing::run!(); | |
| 197 | | ^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 198 | | | |
| 199 | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` | |
| 200 | = note: this error originates in the macro `nonfatal_parsing::run` (in Nightly builds, run with -Z macro-backtrace for more info) | |
| 201 | ||
| 202 | 202 | error: aborting due to 22 previous errors |
| 203 | 203 | |
| 204 | 204 | For more information about this error, try `rustc --explain E0768`. |
tests/ui/proc-macro/nonfatal-parsing.stdout+5-1| ... | ... | @@ -52,15 +52,19 @@ Err(LexError("not a literal")) |
| 52 | 52 | Ok(TokenStream [Ident { ident: "r", span: Span }, Literal { kind: Char, symbol: "r", suffix: None, span: Span }]) |
| 53 | 53 | Ok(TokenStream [Ident { ident: "c", span: Span }, Literal { kind: Char, symbol: "r", suffix: None, span: Span }]) |
| 54 | 54 | Ok(TokenStream []) |
| 55 | Err(LexError("failed to parse to tokenstream")) | |
| 55 | 56 | Ok(TokenStream [Literal { kind: ErrWithGuar, symbol: "0b2", suffix: None, span: Span }]) |
| 56 | 57 | Ok(TokenStream [Literal { kind: ErrWithGuar, symbol: "0b", suffix: Some("f32"), span: Span }]) |
| 57 | 58 | Ok(TokenStream [Literal { kind: ErrWithGuar, symbol: "0b0.0", suffix: Some("f32"), span: Span }]) |
| 58 | 59 | Ok(TokenStream [Literal { kind: ErrWithGuar, symbol: "'''", suffix: None, span: Span }]) |
| 59 | 60 | Ok(TokenStream [Literal { kind: ErrWithGuar, symbol: "'\n'", suffix: None, span: Span }]) |
| 60 | Ok(TokenStream [Literal { kind: ErrWithGuar, symbol: "0b2", suffix: None, span: Span }]) | |
| 61 | Err(LexError("failed to parse to tokenstream")) | |
| 62 | Err(LexError("failed to parse to literal")) | |
| 61 | 63 | Ok(Literal { kind: ErrWithGuar, symbol: "0b2", suffix: None, span: Span }) |
| 62 | 64 | Ok(Literal { kind: ErrWithGuar, symbol: "0b", suffix: Some("f32"), span: Span }) |
| 63 | 65 | Ok(Literal { kind: ErrWithGuar, symbol: "0b0.0", suffix: Some("f32"), span: Span }) |
| 64 | 66 | Ok(Literal { kind: ErrWithGuar, symbol: "'''", suffix: None, span: Span }) |
| 65 | 67 | Ok(Literal { kind: ErrWithGuar, symbol: "'\n'", suffix: None, span: Span }) |
| 68 | Err(LexError("failed to parse to literal")) | |
| 66 | 69 | Err(LexError("comment or whitespace around literal")) |
| 70 | Ok(TokenStream [Literal { kind: ErrWithGuar, symbol: "0b2", suffix: None, span: Span }]) |