I have zero experience in Rust, so maybe I shouldn't comment on an intermediate tutorial, but just some thoughts. I'm sure the answers to most of this are out there, this is more stream of consciousness...

"let i = 1", so let isn't picky about types, and types can be implied. In the 'fn foo(i: i64)' we see the "<name>: <type>" syntax, which I'm not an immediate fan of that, but no big deal.

We have value types, defined as a 'struct' with a 'Copy' flag. The "impl Copy for Info {}" syntax seems weird, and the "#[derive(Copy)]" only slightly better. Also, why does the struct have a hanging comma after the last (only) member?

Next we add some methods to the Bob struct. Seems like there are multiple ways, depending on the type of method? 'new' is just nested inside an 'impl Bob' but 'Drop' is more explicitly nested inside 'impl Drop for Bob' and then a lowercase 'drop' function. Huh.

Inside the 'new' function we see the first use of return values. And starting to catch on that Rust likes chatty syntax, e.g. the '->' before the return type. But yet, a very implicit structure to both initializing and returning the new 'Bob' object! I get the sinking feeling the 'name: name.to_string()' in the Bob initializer is important, and that '{ name: name }' would sadly not work... Not loving the underscore in method names.

I guess the 'drop' function is a first example of an instance method, identified by having '&self' or in this case '&mut self'. For a function that internally doesn't explicitly mutate bob, it's curious to see the &mut in that case. I'm going to guess 'drop' is a special case which always must be 'mut'.

The next step is "make bob value format-able when outputting to console" which sounds an awful lot like implementing to_string() but is accomplished through the 'Show::fmt' trait which is implemented using 'fmt::Show'. Is it really called the "Show::fmt" trait, and not the "fmt::Show" trait?

Here's where I like the syntax less and less: "fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result". Why must 'f' be 'mut' here? Why is the '&mut' before the type and not before the name? The one colon for name/value versus two colons for namespace is starting to hurt. Why a double colon instead of a dot? Also, I have to figure out what are all these ampersands are actually doing... they are notably absent from the 'black_hole' function.

Skipping ahead... owned values can be mutated, you just have to flag it with 'let mut'. Almost wish that was simply 'met' vs 'let', or even 'mlet'. Any owner can flag their value mutable, it doesn't have to start that way.

Then we get to "fn mutate(mut value: Bob) { ... }". Earlier we saw the 'fmt' function apply 'mut' before the type definition, here mut keyword is before the variable name. Is this the same, or something different happening? It seems weird there's not just one place to put the 'mut' flag.

BTW, can you really not just do 'bob.name = "mutant";' versus 'bob.name = String::from_str("mutant");'? Up until this point string handling seems reasonably sane.

Further down we start putting things on the heap instead of stack. In 'let bob = Box::new(Bob::new("A"));' -- do you have to always 'Box::new' to get to the heap, or is there a way to define Bob as always living on the heap, i.e. 'class' vs 'struct'? ... I think I spoke too soon, because further down when it takes all of 'Rc::new(RefCell::new(Bob::new("A")))" to simply have a stack pointer to a mutable instance on the heap, I think I'm ready to bolt.

It's an impressive level of control over the semantics of how objects are created and destroyed without having to explicitly control every aspect of memory management, and there do seem to be a lot of follow-on benefits for going through all this trouble, but perhaps by 2.0 they will have made strides to improve the syntax to something a bit less obnoxious.