Add unsafe example
This commit is contained in:
parent
6d65d88b76
commit
6cf7aa9000
@ -36,6 +36,7 @@
|
||||
<cargoProject FILE="$PROJECT_DIR$/gui/Cargo.toml" />
|
||||
<cargoProject FILE="$PROJECT_DIR$/blog/Cargo.toml" />
|
||||
<cargoProject FILE="$PROJECT_DIR$/pattern_matching/Cargo.toml" />
|
||||
<cargoProject FILE="$PROJECT_DIR$/unsafe_blocks/Cargo.toml" />
|
||||
</component>
|
||||
<component name="ComposerJsonPluginSettings">
|
||||
<unboundedVersionInspectionSettings>
|
||||
|
@ -145,6 +145,10 @@
|
||||
<sourceFolder url="file://$MODULE_DIR$/pattern_matching/examples" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/pattern_matching/tests" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/pattern_matching/benches" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/unsafe_blocks/src" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/unsafe_blocks/examples" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/unsafe_blocks/tests" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/unsafe_blocks/benches" isTestSource="true" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/add/add-one/target" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/add/adder/target" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/adder/target" />
|
||||
@ -179,6 +183,7 @@
|
||||
<excludeFolder url="file://$MODULE_DIR$/threads/target" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/trait_objects/target" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/twelve_days_of_christmas/target" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/unsafe_blocks/target" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/variables/target" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
|
@ -2,6 +2,8 @@
|
||||
<project version="4">
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="c8f42924-1cd2-4b1c-bcff-602a3368bb16" name="Default Changelist" comment="">
|
||||
<change afterPath="$PROJECT_DIR$/unsafe_blocks/Cargo.toml" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/unsafe_blocks/src/main.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/.idea/misc.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/misc.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/.idea/rust.iml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/rust.iml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||
@ -15,10 +17,10 @@
|
||||
<component name="FileEditorManager">
|
||||
<leaf>
|
||||
<file pinned="false" current-in-tab="true">
|
||||
<entry file="file://$PROJECT_DIR$/pattern_matching/src/main.rs">
|
||||
<entry file="file://$PROJECT_DIR$/unsafe_blocks/src/main.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="903">
|
||||
<caret line="194" column="24" selection-start-line="194" selection-start-column="24" selection-end-line="194" selection-end-column="24" />
|
||||
<state relative-caret-position="552">
|
||||
<caret line="40" column="56" selection-start-line="40" selection-start-column="56" selection-end-line="40" selection-end-column="56" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
@ -52,7 +54,6 @@
|
||||
<component name="IdeDocumentHistory">
|
||||
<option name="CHANGED_PATHS">
|
||||
<list>
|
||||
<option value="$PROJECT_DIR$/rectangles/src/main.rs" />
|
||||
<option value="$PROJECT_DIR$/enums/src/main.rs" />
|
||||
<option value="$PROJECT_DIR$/modules/src/sound.rs" />
|
||||
<option value="$PROJECT_DIR$/modules/src/performance_group.rs" />
|
||||
@ -103,6 +104,7 @@
|
||||
<option value="$PROJECT_DIR$/blog/src/main.rs" />
|
||||
<option value="$PROJECT_DIR$/blog/Cargo.toml" />
|
||||
<option value="$PROJECT_DIR$/pattern_matching/src/main.rs" />
|
||||
<option value="$PROJECT_DIR$/unsafe_blocks/src/main.rs" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
@ -112,11 +114,11 @@
|
||||
<annotation-enable>false</annotation-enable>
|
||||
<other-services-enabled>false</other-services-enabled>
|
||||
</component>
|
||||
<component name="ProjectFrameBounds">
|
||||
<option name="x" value="1680" />
|
||||
<option name="y" value="-410" />
|
||||
<component name="ProjectFrameBounds" extendedState="6">
|
||||
<option name="x" value="1920" />
|
||||
<option name="y" value="582" />
|
||||
<option name="width" value="1050" />
|
||||
<option name="height" value="1657" />
|
||||
<option name="height" value="877" />
|
||||
</component>
|
||||
<component name="ProjectLevelVcsManager" settingsEditedManually="true">
|
||||
<ConfirmationsSetting value="1" id="Add" />
|
||||
@ -136,12 +138,12 @@
|
||||
<path>
|
||||
<item name="rust" type="3d21c010:ScopeViewTreeModel$ProjectNode" />
|
||||
<item name="rust" type="2674bda8:ScopeViewTreeModel$GroupNode" />
|
||||
<item name="pattern_matching" type="9f88c78c:ScopeViewTreeModel$FileNode" />
|
||||
<item name="unsafe_blocks" type="9f88c78c:ScopeViewTreeModel$FileNode" />
|
||||
</path>
|
||||
<path>
|
||||
<item name="rust" type="3d21c010:ScopeViewTreeModel$ProjectNode" />
|
||||
<item name="rust" type="2674bda8:ScopeViewTreeModel$GroupNode" />
|
||||
<item name="pattern_matching" type="9f88c78c:ScopeViewTreeModel$FileNode" />
|
||||
<item name="unsafe_blocks" type="9f88c78c:ScopeViewTreeModel$FileNode" />
|
||||
<item name="src" type="9f88c78c:ScopeViewTreeModel$FileNode" />
|
||||
</path>
|
||||
</expand>
|
||||
@ -175,7 +177,7 @@
|
||||
</component>
|
||||
<component name="PropertiesComponent">
|
||||
<property name="JavaScriptWeakerCompletionTypeGuess" value="true" />
|
||||
<property name="com.android.tools.idea.instantapp.provision.ProvisionBeforeRunTaskProvider.myTimeStamp" value="1549488475930" />
|
||||
<property name="com.android.tools.idea.instantapp.provision.ProvisionBeforeRunTaskProvider.myTimeStamp" value="1549557641362" />
|
||||
<property name="javascript.nodejs.core.library.configured.version" value="7.1.0" />
|
||||
<property name="js.eslint.eslintPackage" value="$USER_HOME$/.yarn-config/global/node_modules/.bin/eslint" />
|
||||
<property name="js.eslint.nodeInterpreter" value="project" />
|
||||
@ -203,7 +205,7 @@
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="RunManager" selected="Cargo Command.Run pattern_matching">
|
||||
<component name="RunManager" selected="Cargo Command.Run unsafe_blocks">
|
||||
<configuration name="<template>" type="TestNG" default="true" selected="false">
|
||||
<option name="MAIN_CLASS_NAME" />
|
||||
<option name="VM_PARAMETERS" value="-ea" />
|
||||
@ -252,13 +254,13 @@
|
||||
<envs />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
<configuration name="Run twelve_days_of_christmas" type="CargoCommandRunConfiguration" factoryName="Cargo Command" temporary="true">
|
||||
<configuration name="Run unsafe_blocks" type="CargoCommandRunConfiguration" factoryName="Cargo Command" temporary="true">
|
||||
<option name="channel" value="DEFAULT" />
|
||||
<option name="command" value="run --package twelve_days_of_christmas --bin twelve_days_of_christmas" />
|
||||
<option name="command" value="run --package unsafe_blocks --bin unsafe_blocks" />
|
||||
<option name="allFeatures" value="false" />
|
||||
<option name="nocapture" value="false" />
|
||||
<option name="backtrace" value="SHORT" />
|
||||
<option name="workingDirectory" value="file://$PROJECT_DIR$/twelve_days_of_christmas" />
|
||||
<option name="workingDirectory" value="file://$PROJECT_DIR$/unsafe_blocks" />
|
||||
<envs />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
@ -281,11 +283,11 @@
|
||||
</configuration>
|
||||
<recent_temporary>
|
||||
<list>
|
||||
<item itemvalue="Cargo Command.Run unsafe_blocks" />
|
||||
<item itemvalue="Cargo Command.Run pattern_matching" />
|
||||
<item itemvalue="Cargo Command.Run blog" />
|
||||
<item itemvalue="Cargo Command.Run gui" />
|
||||
<item itemvalue="Cargo Command.Test lib::tests" />
|
||||
<item itemvalue="Cargo Command.Run twelve_days_of_christmas" />
|
||||
</list>
|
||||
</recent_temporary>
|
||||
</component>
|
||||
@ -322,11 +324,11 @@
|
||||
</history-entry>
|
||||
</component>
|
||||
<component name="ToolWindowManager">
|
||||
<frame x="1680" y="-410" width="1050" height="1657" extended-state="6" />
|
||||
<frame x="1920" y="-438" width="1080" height="1897" extended-state="6" />
|
||||
<editor active="true" />
|
||||
<layout>
|
||||
<window_info content_ui="combo" id="Project" order="0" sideWeight="0.49586776" visible="true" weight="0.26141885" />
|
||||
<window_info id="Structure" order="1" sideWeight="0.5041322" side_tool="true" visible="true" weight="0.26141885" />
|
||||
<window_info content_ui="combo" id="Project" order="0" sideWeight="0.496614" visible="true" weight="0.2540132" />
|
||||
<window_info id="Structure" order="1" sideWeight="0.503386" side_tool="true" visible="true" weight="0.2540132" />
|
||||
<window_info id="Image Layers" order="2" />
|
||||
<window_info id="Designer" order="3" />
|
||||
<window_info id="Capture Tool" order="4" />
|
||||
@ -334,7 +336,7 @@
|
||||
<window_info id="Cargo" order="6" sideWeight="0.49791494" weight="0.3286119" />
|
||||
<window_info anchor="bottom" id="Message" order="0" />
|
||||
<window_info anchor="bottom" id="Find" order="1" weight="0.32979318" />
|
||||
<window_info active="true" anchor="bottom" id="Run" order="2" visible="true" weight="0.29696578" />
|
||||
<window_info active="true" anchor="bottom" id="Run" order="2" visible="true" weight="0.2571269" />
|
||||
<window_info anchor="bottom" id="Debug" order="3" weight="0.4" />
|
||||
<window_info anchor="bottom" id="Cvs" order="4" weight="0.25" />
|
||||
<window_info anchor="bottom" id="Inspection" order="5" weight="0.4" />
|
||||
@ -356,13 +358,6 @@
|
||||
<option name="version" value="1" />
|
||||
</component>
|
||||
<component name="editorHistoryManager">
|
||||
<entry file="file://$PROJECT_DIR$/structs/src/main.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="624">
|
||||
<caret line="39" lean-forward="true" selection-start-line="39" selection-end-line="39" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/slices/src/main.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="704">
|
||||
@ -789,8 +784,15 @@
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/pattern_matching/src/main.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="903">
|
||||
<caret line="194" column="24" selection-start-line="194" selection-start-column="24" selection-end-line="194" selection-end-column="24" />
|
||||
<state relative-caret-position="2752">
|
||||
<caret line="172" column="10" lean-forward="true" selection-start-line="172" selection-start-column="10" selection-end-line="172" selection-end-column="10" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/unsafe_blocks/src/main.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="552">
|
||||
<caret line="40" column="56" selection-start-line="40" selection-start-column="56" selection-end-line="40" selection-end-column="56" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
|
7
unsafe_blocks/Cargo.toml
Normal file
7
unsafe_blocks/Cargo.toml
Normal file
@ -0,0 +1,7 @@
|
||||
[package]
|
||||
name = "unsafe_blocks"
|
||||
version = "0.1.0"
|
||||
authors = ["Timothy Warren <twarren@nabancard.com>"]
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
95
unsafe_blocks/src/main.rs
Normal file
95
unsafe_blocks/src/main.rs
Normal file
@ -0,0 +1,95 @@
|
||||
//! Unsafe Example
|
||||
//!
|
||||
//! In Rust, unsafe means less automated safety, not no safety. It's an
|
||||
//! escape hatch for code not normally allowed by the Rust compiler.
|
||||
//!
|
||||
//! Unsafe code allows the following 4 abilities:
|
||||
//!
|
||||
//! 1. Dereferencing raw pointers
|
||||
//! 2. Calling an unsafe function or method
|
||||
//! 3. Acessing/Mutating a mutable static variable (global)
|
||||
//! 4. Implementing an unsafe trait
|
||||
use std::slice;
|
||||
|
||||
extern "C" {
|
||||
fn abs(input: i32) -> i32;
|
||||
}
|
||||
|
||||
// Immutable static variable (global) - safe
|
||||
static HELLO_WORLD: &str = "Hello, world!";
|
||||
|
||||
// Mutable static variable - unsafe to access or mutate
|
||||
static mut COUNTER: u32 = 0;
|
||||
|
||||
fn raw_pointer() {
|
||||
let mut num = 5;
|
||||
|
||||
// Casting references to raw pointers
|
||||
// Raw pointers can be created in safe code,
|
||||
// but can only be dereferenced in unsafe code
|
||||
let r1 = &num as *const i32;
|
||||
let r2 = &mut num as *mut i32;
|
||||
|
||||
unsafe {
|
||||
println!("r1 is: {}", *r1);
|
||||
println!("r2 is: {}", *r2);
|
||||
}
|
||||
}
|
||||
|
||||
/// An unsafe function can only be called within an unsafe block
|
||||
/// This is essentially the same as wrapping the entire function in an unsafe block,
|
||||
/// as an unsafe block in the function body is redundant
|
||||
unsafe fn dangerous() {}
|
||||
|
||||
/// A 'safe' function can wrap unsafe code
|
||||
fn split_at_mut(slice: &mut [i32], mid: usize) -> (&mut [i32], &mut [i32]) {
|
||||
let len = slice.len();
|
||||
let ptr = slice.as_mut_ptr(); // Get the raw pointer of the slice
|
||||
|
||||
assert!(mid <= len);
|
||||
|
||||
unsafe {
|
||||
// These slice methods are unsafe because they require a valid pointer.
|
||||
// Since the Rust compiler can not verify the safety of the pointers,
|
||||
// the calls must be in an unsafe block. The function is still considered
|
||||
// safe, though, because the original pointer is valid, and the bounds
|
||||
// of the slice are verified with the assert call.
|
||||
(
|
||||
slice::from_raw_parts_mut(ptr, mid),
|
||||
slice::from_raw_parts_mut(ptr.offset(mid as isize), len - mid)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// A call to a function from a foreign programming language is considered
|
||||
/// unsafe, as rust can not verify the safety of the external code.
|
||||
/// While this can be wrapped in a 'safe' function, it is (unfortunately) up to the programmer
|
||||
/// to make sure the call is actually safe
|
||||
fn c_library_call() {
|
||||
unsafe {
|
||||
println!("Absolute value of -3 according to C: {}", abs(-3));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Mutable static variables (globals) are unsafe to access
|
||||
/// or mutate due to the possibility of data races in multithreaded code
|
||||
fn add_to_count(inc: u32) {
|
||||
unsafe {
|
||||
COUNTER += inc; // Mutating a mutable static variable is unsafe
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn main() {
|
||||
raw_pointer();
|
||||
|
||||
add_to_count(3);
|
||||
|
||||
unsafe {
|
||||
dangerous();
|
||||
println!("COUNTER: {}", COUNTER); // Accessing a mutable static variable is unsafe
|
||||
}
|
||||
|
||||
c_library_call();
|
||||
}
|
Loading…
Reference in New Issue
Block a user