<!DOCTYPE HTML> <html lang="en"> <head> <meta charset="UTF-8"> <title>Coercions - </title> <meta content="text/html; charset=utf-8" http-equiv="Content-Type"> <meta name="description" content=""> <meta name="viewport" content="width=device-width, initial-scale=1"> <base href=""> <link rel="stylesheet" href="book.css"> <link href="https://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800" rel="stylesheet" type="text/css"> <link href="https://fonts.googleapis.com/css?family=Source+Code+Pro:500" rel="stylesheet" type="text/css"> <link rel="shortcut icon" href="favicon.png"> <!-- Font Awesome --> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css"> <link rel="stylesheet" href="highlight.css"> <link rel="stylesheet" href="tomorrow-night.css"> <!-- MathJax --> <script type="text/javascript" src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script> <!-- Fetch JQuery from CDN but have a local fallback --> <script src="https://code.jquery.com/jquery-2.1.4.min.js"></script> <script> if (typeof jQuery == 'undefined') { document.write(unescape("%3Cscript src='jquery.js'%3E%3C/script%3E")); } </script> </head> <body class="light"> <!-- Set the theme before any content is loaded, prevents flash --> <script type="text/javascript"> var theme = localStorage.getItem('theme'); if (theme == null) { theme = 'light'; } $('body').removeClass().addClass(theme); </script> <!-- Hide / unhide sidebar before it is displayed --> <script type="text/javascript"> var sidebar = localStorage.getItem('sidebar'); if (sidebar === "hidden") { $("html").addClass("sidebar-hidden") } else if (sidebar === "visible") { $("html").addClass("sidebar-visible") } </script> <div id="sidebar" class="sidebar"> <ul class="chapter"><li class="affix"><a href="README.html">Introduction</a></li><li><a href="meet-safe-and-unsafe.html"><strong>1.</strong> Meet Safe and Unsafe</a></li><li><ul class="section"><li><a href="safe-unsafe-meaning.html"><strong>1.1.</strong> How Safe and Unsafe Interact</a></li><li><a href="working-with-unsafe.html"><strong>1.2.</strong> Working with Unsafe</a></li></ul></li><li><a href="data.html"><strong>2.</strong> Data Layout</a></li><li><ul class="section"><li><a href="repr-rust.html"><strong>2.1.</strong> repr(Rust)</a></li><li><a href="exotic-sizes.html"><strong>2.2.</strong> Exotically Sized Types</a></li><li><a href="other-reprs.html"><strong>2.3.</strong> Other reprs</a></li></ul></li><li><a href="ownership.html"><strong>3.</strong> Ownership</a></li><li><ul class="section"><li><a href="references.html"><strong>3.1.</strong> References</a></li><li><a href="lifetimes.html"><strong>3.2.</strong> Lifetimes</a></li><li><a href="lifetime-mismatch.html"><strong>3.3.</strong> Limits of Lifetimes</a></li><li><a href="lifetime-elision.html"><strong>3.4.</strong> Lifetime Elision</a></li><li><a href="unbounded-lifetimes.html"><strong>3.5.</strong> Unbounded Lifetimes</a></li><li><a href="hrtb.html"><strong>3.6.</strong> Higher-Rank Trait Bounds</a></li><li><a href="subtyping.html"><strong>3.7.</strong> Subtyping and Variance</a></li><li><a href="dropck.html"><strong>3.8.</strong> Drop Check</a></li><li><a href="phantom-data.html"><strong>3.9.</strong> PhantomData</a></li><li><a href="borrow-splitting.html"><strong>3.10.</strong> Splitting Borrows</a></li></ul></li><li><a href="conversions.html"><strong>4.</strong> Type Conversions</a></li><li><ul class="section"><li><a href="coercions.html" class="active"><strong>4.1.</strong> Coercions</a></li><li><a href="dot-operator.html"><strong>4.2.</strong> The Dot Operator</a></li><li><a href="casts.html"><strong>4.3.</strong> Casts</a></li><li><a href="transmutes.html"><strong>4.4.</strong> Transmutes</a></li></ul></li><li><a href="uninitialized.html"><strong>5.</strong> Uninitialized Memory</a></li><li><ul class="section"><li><a href="checked-uninit.html"><strong>5.1.</strong> Checked</a></li><li><a href="drop-flags.html"><strong>5.2.</strong> Drop Flags</a></li><li><a href="unchecked-uninit.html"><strong>5.3.</strong> Unchecked</a></li></ul></li><li><a href="obrm.html"><strong>6.</strong> Ownership Based Resource Management</a></li><li><ul class="section"><li><a href="constructors.html"><strong>6.1.</strong> Constructors</a></li><li><a href="destructors.html"><strong>6.2.</strong> Destructors</a></li><li><a href="leaking.html"><strong>6.3.</strong> Leaking</a></li></ul></li><li><a href="unwinding.html"><strong>7.</strong> Unwinding</a></li><li><ul class="section"><li><a href="exception-safety.html"><strong>7.1.</strong> Exception Safety</a></li><li><a href="poisoning.html"><strong>7.2.</strong> Poisoning</a></li></ul></li><li><a href="concurrency.html"><strong>8.</strong> Concurrency</a></li><li><ul class="section"><li><a href="races.html"><strong>8.1.</strong> Races</a></li><li><a href="send-and-sync.html"><strong>8.2.</strong> Send and Sync</a></li><li><a href="atomics.html"><strong>8.3.</strong> Atomics</a></li></ul></li><li><a href="vec.html"><strong>9.</strong> Implementing Vec</a></li><li><ul class="section"><li><a href="vec-layout.html"><strong>9.1.</strong> Layout</a></li><li><a href="vec-alloc.html"><strong>9.2.</strong> Allocating</a></li><li><a href="vec-push-pop.html"><strong>9.3.</strong> Push and Pop</a></li><li><a href="vec-dealloc.html"><strong>9.4.</strong> Deallocating</a></li><li><a href="vec-deref.html"><strong>9.5.</strong> Deref</a></li><li><a href="vec-insert-remove.html"><strong>9.6.</strong> Insert and Remove</a></li><li><a href="vec-into-iter.html"><strong>9.7.</strong> IntoIter</a></li><li><a href="vec-raw.html"><strong>9.8.</strong> RawVec</a></li><li><a href="vec-drain.html"><strong>9.9.</strong> Drain</a></li><li><a href="vec-zsts.html"><strong>9.10.</strong> Handling Zero-Sized Types</a></li><li><a href="vec-final.html"><strong>9.11.</strong> Final Code</a></li></ul></li><li><a href="arc-and-mutex.html"><strong>10.</strong> Implementing Arc and Mutex</a></li><li><a href="ffi.html"><strong>11.</strong> FFI</a></li></ul> </div> <div id="page-wrapper" class="page-wrapper"> <div class="page"> <div id="menu-bar" class="menu-bar"> <div class="left-buttons"> <i id="sidebar-toggle" class="fa fa-bars"></i> <i id="theme-toggle" class="fa fa-paint-brush"></i> </div> <h1 class="menu-title"></h1> <div class="right-buttons"> <i id="print-button" class="fa fa-print" title="Print this book"></i> </div> </div> <div id="content" class="content"> <a class="header" href="coercions.html#coercions" id="coercions"><h1>Coercions</h1></a> <p>Types can implicitly be coerced to change in certain contexts. These changes are generally just <em>weakening</em> of types, largely focused around pointers and lifetimes. They mostly exist to make Rust "just work" in more cases, and are largely harmless.</p> <p>Here's all the kinds of coercion:</p> <p>Coercion is allowed between the following types:</p> <ul> <li>Transitivity: <code>T_1</code> to <code>T_3</code> where <code>T_1</code> coerces to <code>T_2</code> and <code>T_2</code> coerces to <code>T_3</code></li> <li>Pointer Weakening: <ul> <li><code>&mut T</code> to <code>&T</code></li> <li><code>*mut T</code> to <code>*const T</code></li> <li><code>&T</code> to <code>*const T</code></li> <li><code>&mut T</code> to <code>*mut T</code></li> </ul> </li> <li>Unsizing: <code>T</code> to <code>U</code> if <code>T</code> implements <code>CoerceUnsized<U></code></li> <li>Deref coercion: Expression <code>&x</code> of type <code>&T</code> to <code>&*x</code> of type <code>&U</code> if <code>T</code> derefs to <code>U</code> (i.e. <code>T: Deref<Target=U></code>)</li> </ul> <p><code>CoerceUnsized<Pointer<U>> for Pointer<T> where T: Unsize<U></code> is implemented for all pointer types (including smart pointers like Box and Rc). Unsize is only implemented automatically, and enables the following transformations:</p> <ul> <li><code>[T; n]</code> => <code>[T]</code></li> <li><code>T</code> => <code>Trait</code> where <code>T: Trait</code></li> <li><code>Foo<..., T, ...></code> => <code>Foo<..., U, ...></code> where: <ul> <li><code>T: Unsize<U></code></li> <li><code>Foo</code> is a struct</li> <li>Only the last field of <code>Foo</code> has type involving <code>T</code></li> <li><code>T</code> is not part of the type of any other fields</li> <li><code>Bar<T>: Unsize<Bar<U>></code>, if the last field of <code>Foo</code> has type <code>Bar<T></code></li> </ul> </li> </ul> <p>Coercions occur at a <em>coercion site</em>. Any location that is explicitly typed will cause a coercion to its type. If inference is necessary, the coercion will not be performed. Exhaustively, the coercion sites for an expression <code>e</code> to type <code>U</code> are:</p> <ul> <li>let statements, statics, and consts: <code>let x: U = e</code></li> <li>Arguments to functions: <code>takes_a_U(e)</code></li> <li>Any expression that will be returned: <code>fn foo() -> U { e }</code></li> <li>Struct literals: <code>Foo { some_u: e }</code></li> <li>Array literals: <code>let x: [U; 10] = [e, ..]</code></li> <li>Tuple literals: <code>let x: (U, ..) = (e, ..)</code></li> <li>The last expression in a block: <code>let x: U = { ..; e }</code></li> </ul> <p>Note that we do not perform coercions when matching traits (except for receivers, see below). If there is an impl for some type <code>U</code> and <code>T</code> coerces to <code>U</code>, that does not constitute an implementation for <code>T</code>. For example, the following will not type check, even though it is OK to coerce <code>t</code> to <code>&T</code> and there is an impl for <code>&T</code>:</p> <pre><code class="language-rust ignore">trait Trait {} fn foo<X: Trait>(t: X) {} impl<'a> Trait for &'a i32 {} fn main() { let t: &mut i32 = &mut 0; foo(t); } </code></pre> <pre><code class="language-text"><anon>:10:5: 10:8 error: the trait bound `&mut i32 : Trait` is not satisfied [E0277] <anon>:10 foo(t); ^~~ </code></pre> </div> <!-- Mobile navigation buttons --> <a href="conversions.html" class="mobile-nav-chapters previous"> <i class="fa fa-angle-left"></i> </a> <a href="dot-operator.html" class="mobile-nav-chapters next"> <i class="fa fa-angle-right"></i> </a> </div> <a href="conversions.html" class="nav-chapters previous" title="You can navigate through the chapters using the arrow keys"> <i class="fa fa-angle-left"></i> </a> <a href="dot-operator.html" class="nav-chapters next" title="You can navigate through the chapters using the arrow keys"> <i class="fa fa-angle-right"></i> </a> </div> <!-- Local fallback for Font Awesome --> <script> if ($(".fa").css("font-family") !== "FontAwesome") { $('<link rel="stylesheet" type="text/css" href="_FontAwesome/css/font-awesome.css">').prependTo('head'); } </script> <!-- Livereload script (if served using the cli tool) --> <script src="highlight.js"></script> <script src="book.js"></script> </body> </html>