From 7160d9220fd3df46e17e11fd25ac2e0665ed2507 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 2 Jul 2015 20:11:48 +0200 Subject: [PATCH 01/11] Add E0128 error explanation --- src/librustc_typeck/diagnostics.rs | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index 549c89599ecd8..01f7db83adfa1 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -1368,6 +1368,26 @@ struct Foo { ``` "##, +E0128: r##" +You declared a type parameter with a default which has the same identifier as +the type parameter. Erroneous code example: + +``` +pub struct Foo; +// error: type parameters with a default cannot use forward declared +// identifiers +``` + +Please verify you used the good type or change the type parameter identifier. +Example: + +``` +pub struct Foo { + value: T +} +``` +"##, + E0131: r##" It is not possible to define `main` with type parameters, or even with function parameters. When `main` is present, it must take no arguments and return `()`. @@ -1978,7 +1998,6 @@ register_diagnostics! { E0122, E0123, E0127, - E0128, E0129, E0130, E0141, From 05fcb2e9bc679d689a92122f4803977c83b878aa Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 2 Jul 2015 20:27:12 +0200 Subject: [PATCH 02/11] Add E0130 error explanation --- src/librustc_typeck/diagnostics.rs | 34 +++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index 01f7db83adfa1..8e6f6a50fa58f 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -1378,8 +1378,8 @@ pub struct Foo; // identifiers ``` -Please verify you used the good type or change the type parameter identifier. -Example: +Please verify that a name clash hasn't been accidentally introduced, and rename +the type parameter if so. Example: ``` pub struct Foo { @@ -1388,6 +1388,35 @@ pub struct Foo { ``` "##, +E0130: r##" +You declared a pattern as an argument in a foreign function declaration. +Erroneous code example: + +``` +extern { + fn foo((a, b): (u32, u32)); // error: patterns aren't allowed in foreign + // function declarations +} +``` + +Please replace the pattern argument with a regular one. Example: + +``` +struct SomeStruct { + a: u32, + b: u32, +} + +extern { + fn foo(s: SomeStruct); // ok! +} +// or +extern { + fn foo(a: (u32, u32)); // ok! +} +``` +"##, + E0131: r##" It is not possible to define `main` with type parameters, or even with function parameters. When `main` is present, it must take no arguments and return `()`. @@ -1999,7 +2028,6 @@ register_diagnostics! { E0123, E0127, E0129, - E0130, E0141, E0159, E0163, From 0d1deb521c79207611f4a9b74811535150f4a031 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 3 Jul 2015 13:31:23 +0200 Subject: [PATCH 03/11] Add E0159 error explanation --- src/librustc_typeck/diagnostics.rs | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index 8e6f6a50fa58f..9663705822524 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -1431,6 +1431,30 @@ fn(isize, *const *const u8) -> isize ``` "##, +E0159: r##" +You tried to use a trait as a struct constructor. Erroneous code example: + +``` +trait TraitNotAStruct {} + +TraitNotAStruct{ value: 0 }; // error: use of trait `TraitNotAStruct` as a + // struct constructor +``` + +Please verify you used the correct type name or please implement the trait +on a struct and use this struct constructor. Example: + +``` +trait TraitNotAStruct {} + +struct Foo { + value: i32 +} + +Foo{ value: 0 }; // ok! +``` +"##, + E0166: r##" This error means that the compiler found a return expression in a function marked as diverging. A function diverges if it has `!` in the place of the @@ -2029,7 +2053,6 @@ register_diagnostics! { E0127, E0129, E0141, - E0159, E0163, E0164, E0167, From 18848ca7846fb6f72f6614fea4fd4a4565f8102a Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 3 Jul 2015 15:40:42 +0200 Subject: [PATCH 04/11] Add E0135 error explanation --- src/librustc/diagnostics.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index eb504d03209f6..8b09161fd9976 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -411,6 +411,24 @@ fn main() { See also https://doc.rust-lang.org/book/unsafe.html "##, +E0135: r##" +You tried to modify the str type, which isn't allowed. Erroneous code +example: + +``` +let s = "salut"; +let c = &mut (*s)[0..1]; // error: modification of string types is not + // allowed +``` + +I you want to modify an str, please use the String type. Example: + +``` +let mut s = "salut"; +let mut c = s[0..1].to_owned(); // ok! +``` +"##, + E0137: r##" This error indicates that the compiler found multiple functions with the `#[main]` attribute. This is an error because there must be a unique entry From d72c3076e1f5099923bdd54f6ab726d796cd8907 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 3 Jul 2015 15:43:14 +0200 Subject: [PATCH 05/11] Add E0134 error explanation --- src/librustc/diagnostics.rs | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index 8b09161fd9976..d616b4f90b825 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -411,6 +411,24 @@ fn main() { See also https://doc.rust-lang.org/book/unsafe.html "##, +E0134: r##" +You tried to modify the str type, which isn't allowed. Erroneous code +example: + +``` +let s = "salut"; +let c = &mut s[0..1]; // error: modification of string types is not + // allowed +``` + +I you want to modify an str, please use the String type. Example: + +``` +let mut s = "salut"; +let mut c = s[0..1].to_owned(); // ok! +``` +"##, + E0135: r##" You tried to modify the str type, which isn't allowed. Erroneous code example: @@ -421,7 +439,7 @@ let c = &mut (*s)[0..1]; // error: modification of string types is not // allowed ``` -I you want to modify an str, please use the String type. Example: +If you want to modify an str, please use the String type. Example: ``` let mut s = "salut"; From 5460650eeccb0d8925b36480d0ccd7db31a757d8 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 4 Jul 2015 18:35:21 +0200 Subject: [PATCH 06/11] Remove E0134 and E0135 error explanation --- src/librustc/diagnostics.rs | 36 ------------------------------ src/librustc_typeck/diagnostics.rs | 21 +++++++++++------ 2 files changed, 14 insertions(+), 43 deletions(-) diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index d616b4f90b825..eb504d03209f6 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -411,42 +411,6 @@ fn main() { See also https://doc.rust-lang.org/book/unsafe.html "##, -E0134: r##" -You tried to modify the str type, which isn't allowed. Erroneous code -example: - -``` -let s = "salut"; -let c = &mut s[0..1]; // error: modification of string types is not - // allowed -``` - -I you want to modify an str, please use the String type. Example: - -``` -let mut s = "salut"; -let mut c = s[0..1].to_owned(); // ok! -``` -"##, - -E0135: r##" -You tried to modify the str type, which isn't allowed. Erroneous code -example: - -``` -let s = "salut"; -let c = &mut (*s)[0..1]; // error: modification of string types is not - // allowed -``` - -If you want to modify an str, please use the String type. Example: - -``` -let mut s = "salut"; -let mut c = s[0..1].to_owned(); // ok! -``` -"##, - E0137: r##" This error indicates that the compiler found multiple functions with the `#[main]` attribute. This is an error because there must be a unique entry diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index 9663705822524..a1fa4218e7062 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -1369,23 +1369,30 @@ struct Foo { "##, E0128: r##" -You declared a type parameter with a default which has the same identifier as -the type parameter. Erroneous code example: +Type parameter defaults can only use parameters that occur before them. +Erroneous code example: ``` -pub struct Foo; +pub struct Foo { + field1: T, + filed2: U, +} // error: type parameters with a default cannot use forward declared // identifiers ``` -Please verify that a name clash hasn't been accidentally introduced, and rename -the type parameter if so. Example: +Since type parameters are evaluated in-order, you may be able to fix this issue +by doing: ``` -pub struct Foo { - value: T +pub struct Foo { + field1: T, + filed2: U, } ``` + +Please also verify that this wasn't because of a name-clash and rename the type +parameter if so. "##, E0130: r##" From 6a3b385cbd6b9044b4447da96aad066e8b257ddf Mon Sep 17 00:00:00 2001 From: Eduard Burtescu Date: Wed, 1 Jul 2015 06:05:17 +0300 Subject: [PATCH 07/11] Feature-gate #[prelude_import]. --- src/librustc_driver/driver.rs | 2 +- src/libsyntax/feature_gate.rs | 6 ++- src/libsyntax/print/pprust.rs | 4 +- src/libsyntax/std_inject.rs | 48 +++++++++++++------ .../feature-gate-prelude_import.rs | 14 ++++++ src/test/pretty/issue-4264.pp | 2 +- 6 files changed, 57 insertions(+), 19 deletions(-) create mode 100644 src/test/compile-fail/feature-gate-prelude_import.rs diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 80c4fc28703ac..ae6136a049ade 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -547,7 +547,7 @@ pub fn phase_2_configure_and_expand(sess: &Session, sess.diagnostic())); krate = time(time_passes, "prelude injection", krate, |krate| - syntax::std_inject::maybe_inject_prelude(krate)); + syntax::std_inject::maybe_inject_prelude(&sess.parse_sess, krate)); time(time_passes, "checking that all macro invocations are gone", &krate, |krate| syntax::ext::expand::check_for_macros(&sess.parse_sess, krate)); diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 3d0cf9236c25c..ab8cf9ae6b64f 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -155,6 +155,9 @@ const KNOWN_FEATURES: &'static [(&'static str, &'static str, Status)] = &[ // Allows the definition of `const fn` functions. ("const_fn", "1.2.0", Active), + + // Allows using #[prelude_import] on glob `use` items. + ("prelude_import", "1.2.0", Active), ]; // (changing above list without updating src/doc/reference.md makes @cmr sad) @@ -265,7 +268,8 @@ pub const KNOWN_ATTRIBUTES: &'static [(&'static str, AttributeType)] = &[ and may be removed in the future")), // used in resolve - ("prelude_import", Whitelisted), + ("prelude_import", Gated("prelude_import", + "`#[prelude_import]` is for use by rustc only")), // FIXME: #14407 these are only looked at on-demand so we can't // guarantee they'll have already been checked diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 3adb73cfa5d6f..6693eed6aced5 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -120,11 +120,13 @@ pub fn print_crate<'a>(cm: &'a CodeMap, // of the feature gate, so we fake them up here. let no_std_meta = attr::mk_word_item(InternedString::new("no_std")); + let prelude_import_meta = attr::mk_word_item(InternedString::new("prelude_import")); // #![feature(no_std)] let fake_attr = attr::mk_attr_inner(attr::mk_attr_id(), attr::mk_list_item(InternedString::new("feature"), - vec![no_std_meta.clone()])); + vec![no_std_meta.clone(), + prelude_import_meta])); try!(s.print_attribute(&fake_attr)); // #![no_std] diff --git a/src/libsyntax/std_inject.rs b/src/libsyntax/std_inject.rs index 021ec4738ed94..3655058653188 100644 --- a/src/libsyntax/std_inject.rs +++ b/src/libsyntax/std_inject.rs @@ -10,16 +10,35 @@ use ast; use attr; -use codemap::DUMMY_SP; +use codemap::{DUMMY_SP, Span, ExpnInfo, NameAndSpan, MacroAttribute}; use codemap; use fold::Folder; use fold; use parse::token::InternedString; use parse::token::special_idents; -use parse::token; +use parse::{token, ParseSess}; use ptr::P; use util::small_vector::SmallVector; +/// Craft a span that will be ignored by the stability lint's +/// call to codemap's is_internal check. +/// The expanded code uses the unstable `#[prelude_import]` attribute. +fn ignored_span(sess: &ParseSess, sp: Span) -> Span { + let info = ExpnInfo { + call_site: DUMMY_SP, + callee: NameAndSpan { + name: "std_inject".to_string(), + format: MacroAttribute, + span: None, + allow_internal_unstable: true, + } + }; + let expn_id = sess.codemap().record_expansion(info); + let mut sp = sp; + sp.expn_id = expn_id; + return sp; +} + pub fn maybe_inject_crates_ref(krate: ast::Crate, alt_std_name: Option) -> ast::Crate { if use_std(&krate) { @@ -29,9 +48,12 @@ pub fn maybe_inject_crates_ref(krate: ast::Crate, alt_std_name: Option) } } -pub fn maybe_inject_prelude(krate: ast::Crate) -> ast::Crate { +pub fn maybe_inject_prelude(sess: &ParseSess, krate: ast::Crate) -> ast::Crate { if use_std(&krate) { - inject_prelude(krate) + let mut fold = PreludeInjector { + span: ignored_span(sess, DUMMY_SP) + }; + fold.fold_crate(krate) } else { krate } @@ -80,8 +102,9 @@ fn inject_crates_ref(krate: ast::Crate, alt_std_name: Option) -> ast::Cr fold.fold_crate(krate) } -struct PreludeInjector; - +struct PreludeInjector { + span: Span +} impl fold::Folder for PreludeInjector { fn fold_crate(&mut self, mut krate: ast::Crate) -> ast::Crate { @@ -107,7 +130,7 @@ impl fold::Folder for PreludeInjector { fn fold_mod(&mut self, mut mod_: ast::Mod) -> ast::Mod { let prelude_path = ast::Path { - span: DUMMY_SP, + span: self.span, global: false, segments: vec![ ast::PathSegment { @@ -131,12 +154,12 @@ impl fold::Folder for PreludeInjector { ident: special_idents::invalid, node: ast::ItemUse(vp), attrs: vec![ast::Attribute { - span: DUMMY_SP, + span: self.span, node: ast::Attribute_ { id: attr::mk_attr_id(), style: ast::AttrOuter, value: P(ast::MetaItem { - span: DUMMY_SP, + span: self.span, node: ast::MetaWord(token::get_name( special_idents::prelude_import.name)), }), @@ -144,14 +167,9 @@ impl fold::Folder for PreludeInjector { }, }], vis: ast::Inherited, - span: DUMMY_SP, + span: self.span, })); fold::noop_fold_mod(mod_, self) } } - -fn inject_prelude(krate: ast::Crate) -> ast::Crate { - let mut fold = PreludeInjector; - fold.fold_crate(krate) -} diff --git a/src/test/compile-fail/feature-gate-prelude_import.rs b/src/test/compile-fail/feature-gate-prelude_import.rs new file mode 100644 index 0000000000000..8bc3df247ec12 --- /dev/null +++ b/src/test/compile-fail/feature-gate-prelude_import.rs @@ -0,0 +1,14 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[prelude_import] //~ ERROR `#[prelude_import]` is for use by rustc only +use std::prelude::v1::*; + +fn main() {} diff --git a/src/test/pretty/issue-4264.pp b/src/test/pretty/issue-4264.pp index c2ed10ce6a187..5f7ce68348a3d 100644 --- a/src/test/pretty/issue-4264.pp +++ b/src/test/pretty/issue-4264.pp @@ -1,4 +1,4 @@ -#![feature(no_std)] +#![feature(no_std, prelude_import)] #![no_std] #[prelude_import] use std::prelude::v1::*; From f29b565e2d73cd0d5e732d6b04bcbb19ce4363b4 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Tue, 7 Jul 2015 09:19:26 -0400 Subject: [PATCH 08/11] Describe lifetime syntax for impl Fixes #26375 --- src/doc/trpl/lifetimes.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/doc/trpl/lifetimes.md b/src/doc/trpl/lifetimes.md index 11d651c5778e3..8e02367b921bc 100644 --- a/src/doc/trpl/lifetimes.md +++ b/src/doc/trpl/lifetimes.md @@ -101,6 +101,8 @@ the lifetime `'a` has snuck in between the `&` and the `mut i32`. We read `&mut i32` as ‘a mutable reference to an i32’ and `&'a mut i32` as ‘a mutable reference to an `i32` with the lifetime `'a`’. +# In `struct`s + You’ll also need explicit lifetimes when working with [`struct`][structs]s: ```rust @@ -137,6 +139,33 @@ x: &'a i32, uses it. So why do we need a lifetime here? We need to ensure that any reference to a `Foo` cannot outlive the reference to an `i32` it contains. +## `impl` blocks + +Let’s implement a method on `Foo`: + +```rust +struct Foo<'a> { + x: &'a i32, +} + +impl<'a> Foo<'a> { + fn x(&self) -> &'a i32 { self.x } +} + +fn main() { + let y = &5; // this is the same as `let _y = 5; let y = &_y;` + let f = Foo { x: y }; + + println!("x is: {}", f.x()); +} +``` + +As you can see, we need to declare a lifetime for `Foo` in the `impl` line. We repeat +`'a` twice, just like on functions: `impl<'a>` defines a lifetime `'a`, and `Foo<'a>` +uses it. + +## Multiple lifetimes + If you have multiple references, you can use the same lifetime multiple times: ```rust From 73df19a206f731a24b0ff7a5e701fa1d337211cd Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Tue, 7 Jul 2015 09:26:23 -0400 Subject: [PATCH 09/11] There are four uses of unsafe, actually I am not mentioning #[unsafe_drop_flag] because it should go away eventually, and also because it's just an attribute, it's not really a use of the `unsafe` keyword. Fixes #26345 --- src/doc/trpl/unsafe.md | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/doc/trpl/unsafe.md b/src/doc/trpl/unsafe.md index e8f1b829061c2..2f92f50bb228c 100644 --- a/src/doc/trpl/unsafe.md +++ b/src/doc/trpl/unsafe.md @@ -8,7 +8,7 @@ this, Rust has a keyword, `unsafe`. Code using `unsafe` has less restrictions than normal code does. Let’s go over the syntax, and then we’ll talk semantics. `unsafe` is used in -two contexts. The first one is to mark a function as unsafe: +four contexts. The first one is to mark a function as unsafe: ```rust unsafe fn danger_will_robinson() { @@ -27,6 +27,19 @@ unsafe { } ``` +The third is for unsafe traits: + +```rust +unsafe trait Scary { } +``` + +And the fourth is for `impl`ementing one of those traits: + +```rust +# unsafe trait Scary { } +unsafe impl Scary for i32 {} +``` + It’s important to be able to explicitly delineate code that may have bugs that cause big problems. If a Rust program segfaults, you can be sure it’s somewhere in the sections marked `unsafe`. From 4b19be36319d6a0398b36a1d529d3defe30e31a2 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Tue, 7 Jul 2015 09:29:04 -0400 Subject: [PATCH 10/11] Not literally all of concurrency is a library Fixes #26344 --- src/doc/trpl/concurrency.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/doc/trpl/concurrency.md b/src/doc/trpl/concurrency.md index ccd769089d251..15c19ece48a14 100644 --- a/src/doc/trpl/concurrency.md +++ b/src/doc/trpl/concurrency.md @@ -10,11 +10,12 @@ system is up to the task, and gives you powerful ways to reason about concurrent code at compile time. Before we talk about the concurrency features that come with Rust, it's important -to understand something: Rust is low-level enough that all of this is provided -by the standard library, not by the language. This means that if you don't like -some aspect of the way Rust handles concurrency, you can implement an alternative -way of doing things. [mio](https://github.com/carllerche/mio) is a real-world -example of this principle in action. +to understand something: Rust is low-level enough that the vast majority of +this is provided by the standard library, not by the language. This means that +if you don't like some aspect of the way Rust handles concurrency, you can +implement an alternative way of doing things. +[mio](https://github.com/carllerche/mio) is a real-world example of this +principle in action. ## Background: `Send` and `Sync` From bc28e64fb3af14d7ff3f47f281fe87126b07cad6 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Tue, 7 Jul 2015 09:23:07 -0400 Subject: [PATCH 11/11] Re-word UB in unsafe guide This incorrectly implied that doing things is fine in unsafe code Fixes #26346 --- src/doc/trpl/unsafe.md | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/doc/trpl/unsafe.md b/src/doc/trpl/unsafe.md index e8f1b829061c2..5b108a5fc1c94 100644 --- a/src/doc/trpl/unsafe.md +++ b/src/doc/trpl/unsafe.md @@ -33,9 +33,21 @@ in the sections marked `unsafe`. # What does ‘safe’ mean? -Safe, in the context of Rust, means “doesn’t do anything unsafe.” Easy! +Safe, in the context of Rust, means ‘doesn’t do anything unsafe’. It’s also +important to know that there are certain behaviors that are probably not +desirable in your code, but are expressly _not_ unsafe: -Okay, let’s try again: what is not safe to do? Here’s a list: +* Deadlocks +* Leaks of memory or other resources +* Exiting without calling destructors +* Integer overflow + +Rust cannot prevent all kinds of software problems. Buggy code can and will be +written in Rust. These things aren’t great, but they don’t qualify as `unsafe` +specifically. + +In addition, the following are all undefined behaviors in Rust, and must be +avoided, even when writing `unsafe` code: * Data races * Dereferencing a null/dangling raw pointer @@ -64,18 +76,6 @@ Okay, let’s try again: what is not safe to do? Here’s a list: [undef]: http://llvm.org/docs/LangRef.html#undefined-values [aliasing]: http://llvm.org/docs/LangRef.html#pointer-aliasing-rules -Whew! That’s a bunch of stuff. It’s also important to notice all kinds of -behaviors that are certainly bad, but are expressly _not_ unsafe: - -* Deadlocks -* Leaks of memory or other resources -* Exiting without calling destructors -* Integer overflow - -Rust cannot prevent all kinds of software problems. Buggy code can and will be -written in Rust. These things aren’t great, but they don’t qualify as `unsafe` -specifically. - # Unsafe Superpowers In both unsafe functions and unsafe blocks, Rust will let you do three things