|  |  |  | @ -234,9 +234,9 @@ fn shortest<'k>(x: &'k str, y: &'k str) { | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | ``` | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | `print_shortest()` simply prints the shorter of its two pass-by-reference | 
			
		
	
		
			
				
					|  |  |  |  | `print_shortest` simply prints the shorter of its two pass-by-reference | 
			
		
	
		
			
				
					|  |  |  |  | string arguments. In Rust, each let binding has its own scope. Let's make the | 
			
		
	
		
			
				
					|  |  |  |  | scopes introduced to `main()` explicit: | 
			
		
	
		
			
				
					|  |  |  |  | scopes introduced to `main` explicit: | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | ```rust,ignore | 
			
		
	
		
			
				
					|  |  |  |  | fn main() { | 
			
		
	
	
		
			
				
					|  |  |  | @ -262,23 +262,23 @@ fn main() { | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | ``` | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | Now we see that the references passed as arguments to `print_shortest()` | 
			
		
	
		
			
				
					|  |  |  |  | Now we see that the references passed as arguments to `print_shortest` | 
			
		
	
		
			
				
					|  |  |  |  | actually have different lifetimes (and thus a different type!) since the values | 
			
		
	
		
			
				
					|  |  |  |  | they refer to were introduced in different scopes. At the call site of | 
			
		
	
		
			
				
					|  |  |  |  | `print_shortest()` the compiler must now check that the lifetimes in the | 
			
		
	
		
			
				
					|  |  |  |  | *caller* (`main()`) are consistent with the lifetimes in the signature of the | 
			
		
	
		
			
				
					|  |  |  |  | *callee* (`print_shortest()`). | 
			
		
	
		
			
				
					|  |  |  |  | `print_shortest` the compiler must now check that the lifetimes in the | 
			
		
	
		
			
				
					|  |  |  |  | *caller* (`main`) are consistent with the lifetimes in the signature of the | 
			
		
	
		
			
				
					|  |  |  |  | *callee* (`print_shortest`). | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | The signature of `print_shortest()` simply requires that both of it's arguments | 
			
		
	
		
			
				
					|  |  |  |  | The signature of `print_shortest` simply requires that both of it's arguments | 
			
		
	
		
			
				
					|  |  |  |  | have the same lifetime (because both arguments are marked with the same | 
			
		
	
		
			
				
					|  |  |  |  | lifetime identifier in the signature). If in `main()` we had done: | 
			
		
	
		
			
				
					|  |  |  |  | lifetime identifier in the signature). If in `main` we had done: | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | ```rust,ignore | 
			
		
	
		
			
				
					|  |  |  |  | print_shortest(&s1, &s1); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | ``` | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | Then this the consistency is trivially proven, since both arguments would have | 
			
		
	
		
			
				
					|  |  |  |  | Then consistency is trivially proven, since both arguments would have | 
			
		
	
		
			
				
					|  |  |  |  | the same lifetime `&'s1` at the call-site. However, for our example, the | 
			
		
	
		
			
				
					|  |  |  |  | arguments have different lifetimes. We don't want Rust to reject the program | 
			
		
	
		
			
				
					|  |  |  |  | because it actually is safe. Instead the compiler uses some rules for | 
			
		
	
	
		
			
				
					|  |  |  | @ -291,7 +291,7 @@ such rule is as follows: | 
			
		
	
		
			
				
					|  |  |  |  | At our call site, the type of the arguments are `&'s1 str` and `&'s2 str`, and | 
			
		
	
		
			
				
					|  |  |  |  | we know that  a `&'s1 str' outlives an `&'s2 str`, so we can substitute `&'s1 | 
			
		
	
		
			
				
					|  |  |  |  | s1` with `&'s2 s2`. After this both arguments are of lifetime `&'s2` and the | 
			
		
	
		
			
				
					|  |  |  |  | call-site is consistent with the signature of `print_shortest()`. | 
			
		
	
		
			
				
					|  |  |  |  | call-site is consistent with the signature of `print_shortest`. | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | [More formally, the basis for the above rule is in *type variance*. Under this | 
			
		
	
		
			
				
					|  |  |  |  | model, you would consider a longer lifetime a sub-type of a shorter lifetime, | 
			
		
	
	
		
			
				
					|  |  |  | @ -321,12 +321,12 @@ fn shortest<'k>(x: &'k str, y: &'k str) -> &'k str { | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | ``` | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | `print_shortest()` has been renamed to `shortest()`, which instead of printing, | 
			
		
	
		
			
				
					|  |  |  |  | `print_shortest` has been renamed to `shortest`, which instead of printing, | 
			
		
	
		
			
				
					|  |  |  |  | now returns the shorter of the two strings. It does this using only references | 
			
		
	
		
			
				
					|  |  |  |  | for efficiency, avoiding the need to re-allocate a new string to pass back to | 
			
		
	
		
			
				
					|  |  |  |  | `main()`. The responsibility of printing the result has been shifted to `main()`. | 
			
		
	
		
			
				
					|  |  |  |  | `main`. The responsibility of printing the result has been shifted to `main`. | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | Let's again de-sugar `main()` by adding explicit scopes and lifetimes: | 
			
		
	
		
			
				
					|  |  |  |  | Let's again de-sugar `main` by adding explicit scopes and lifetimes: | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | ```rust,ignore | 
			
		
	
		
			
				
					|  |  |  |  | fn main() { | 
			
		
	
	
		
			
				
					|  |  |  | @ -344,9 +344,9 @@ fn main() { | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | ``` | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | Again, at the call-site of `shortest()` the comipiler needs to check the | 
			
		
	
		
			
				
					|  |  |  |  | Again, at the call-site of `shortest` the comipiler needs to check the | 
			
		
	
		
			
				
					|  |  |  |  | consistency of the arguments in the caller with the signature of the callee. | 
			
		
	
		
			
				
					|  |  |  |  | The signature of `shortest()` fisrt says that the two reference arguments have | 
			
		
	
		
			
				
					|  |  |  |  | The signature of `shortest` fisrt says that the two reference arguments have | 
			
		
	
		
			
				
					|  |  |  |  | the same lifetime, which can be prove ok in the same way as before, thus giving | 
			
		
	
		
			
				
					|  |  |  |  | us: | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  |  | @ -401,7 +401,7 @@ fn main() { | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | ``` | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | Then at the call-site of `shortest()`: | 
			
		
	
		
			
				
					|  |  |  |  | Then at the call-site of `shortest`: | 
			
		
	
		
			
				
					|  |  |  |  |  * `&'s1 s1` outlives `&'s2 s2`, so we can replace the first argument with `&'s2 s1`. | 
			
		
	
		
			
				
					|  |  |  |  |  * `&'res str` lives shorter than `'&s2`, so the return value lifetime can become `res: &'s2 str` | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  |  | @ -411,6 +411,6 @@ Leaving us with: | 
			
		
	
		
			
				
					|  |  |  |  | res: &'s2 str = shortest(&'s2 s1, &'s2 s2); | 
			
		
	
		
			
				
					|  |  |  |  | ``` | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | Which matches the signature of `shortest()` and thus this compiles. | 
			
		
	
		
			
				
					|  |  |  |  | Which matches the signature of `shortest` and thus this compiles. | 
			
		
	
		
			
				
					|  |  |  |  | Intuitively, the return reference can't point to a freed value as the values | 
			
		
	
		
			
				
					|  |  |  |  | live strictly longer than the return reference. | 
			
		
	
	
		
			
				
					|  |  |  | 
 |