about summary refs log tree commit diff
path: root/src/test
AgeCommit message (Collapse)AuthorLines
2017-11-08std: Remove `rand` crate and moduleAlex Crichton-28/+12
This commit removes the `rand` crate from the standard library facade as well as the `__rand` module in the standard library. Neither of these were used in any meaningful way in the standard library itself. The only need for randomness in libstd is to initialize the thread-local keys of a `HashMap`, and that unconditionally used `OsRng` defined in the standard library anyway. The cruft of the `rand` crate and the extra `rand` support in the standard library makes libstd slightly more difficult to port to new platforms, namely WebAssembly which doesn't have any randomness at all (without interfacing with JS). The purpose of this commit is to clarify and streamline randomness in libstd, focusing on how it's only required in one location, hashmap seeds. Note that the `rand` crate out of tree has almost always been a drop-in replacement for the `rand` crate in-tree, so any usage (accidental or purposeful) of the crate in-tree should switch to the `rand` crate on crates.io. This then also has the further benefit of avoiding duplication (mostly) between the two crates!
2017-11-09Auto merge of #45688 - Gankro:layout-tests, r=alexcrichtonbors-0/+173
Add reftest that checks the layout of repr(int) on non-c-like enums This verifies the first layout specified in https://github.com/rust-lang/rfcs/pull/2195 The second (`repr(C)`) layout isn't included here because it doesn't actually exist today. However if/when that's implemented a second test could be fairly easily derived from this one. CC @eddyb
2017-11-08Auto merge of #45867 - michaelwoerister:check-ich-stability, r=nikomatsakisbors-27/+64
incr.comp.: Verify stability of incr. comp. hashes and clean up various other things. The main contribution of this PR is that it adds the `-Z incremental-verify-ich` functionality. Normally, when the red-green tracking system determines that a certain query result has not changed, it does not re-compute the incr. comp. hash (ICH) for that query result because that hash is already known. `-Z incremental-verify-ich` tells the compiler to re-hash the query result and compare the new hash against the cached hash. This is a rather thorough way of - testing hashing implementation stability, - finding missing `[input]` annotations on `DepNodes`, and - finding missing read-edges, since both a missed read and a missing `[input]` annotation can lead to something being marked as green instead of red and thus will have a different hash than it should have. Case in point, implementing this verification logic and activating it for all `src/test/incremental` tests has revealed several such oversights, all of which are fixed in this PR. r? @nikomatsakis
2017-11-08Auto merge of #45452 - estebank:colon-typo, r=nikomatsakisbors-31/+32
Detect `=` -> `:` typo in let bindings When encountering a let binding type error, attempt to parse as initializer instead. If successful, it is likely just a typo: ```rust fn main() { let x: Vec::with_capacity(10); } ``` ``` error: expected type, found `10` --> file.rs:3:31 | 3 | let x: Vec::with_capacity(10, 20); | -- ^^ | || | |help: did you mean assign here?: `=` | while parsing the type for `x` ``` Fix #43703.
2017-11-08Add reftest that checks the layout of repr(int) on non-c-like enumsAlexis Beingessner-0/+173
This verifies the layout specified in rfc #2195
2017-11-08Auto merge of #45205 - rkruppe:saturating-casts, r=eddybbors-0/+290
Saturating casts between integers and floats Introduces a new flag, `-Z saturating-float-casts`, which makes code generation for int->float and float->int casts safe (`undef`-free), implementing [the saturating semantics laid out by](https://github.com/rust-lang/rust/issues/10184#issuecomment-299229143) @jorendorff for float->int casts and overflowing to infinity for `u128::MAX` -> `f32`. Constant evaluation in trans was changed to behave like HIR const eval already did, i.e., saturate for u128->f32 and report an error for problematic float->int casts. Many thanks to @eddyb, whose APFloat port simplified many parts of this patch, and made HIR constant evaluation recognize dangerous float casts as mentioned above. Also thanks to @ActuallyaDeviloper whose branchless implementation served as inspiration for this implementation. cc #10184 #41799 fixes #45134
2017-11-08Auto merge of #45866 - JohnColanduoni:issue-45731, r=alexcrichtonbors-0/+34
Disable `mmap` in `libbacktrace` on Apple platforms Fixes #45731 libbacktrace uses mmap if available to map ranges of the files containing debug information. On macOS `mmap` will succeed even if the mapped range does not exist, and a SIGBUS (with an unusual EXC_BAD_ACCESS code 10) will occur when the program attempts to page in the memory. To combat this we force `libbacktrace` to be built with the simple `read` based fallback on Apple platforms.
2017-11-08Disable u128 <-> float tests on emscriptenRobin Kruppe-29/+39
2017-11-08Auto merge of #45575 - michaelwoerister:tweak-inline-trans-items, r=nikomatsakisbors-391/+483
Only instantiate inline- and const-fns if they are referenced (again). It seems that we have regressed on not translating `#[inline]` functions unless they are actually used. This should bring back this optimization. I also added a regression test this time so it doesn't happen again accidentally. Fixes #40392. r? @alexcrichton UPDATE & PSA --------------------- This patch **makes translation very lazy** -- in general this is a good thing (we don't want the compiler to do unnecessary work) but it has two consequences: 1. Some error messages are only generated when an item is actually translated. Consequently, this patch will lead to more cases where the compiler will only start emitting errors when the erroneous function is actually used. This has always been true to some extend (e.g. when passing generic values to an intrinsic) but since this is something user-facing it's worth mentioning. 2. When writing tests, one has to make sure that the functions in question are actually generated. In other words, it must not be dead code. This can usually be achieved by either 1. making sure the function is exported from the resulting binary or 2. by making sure the function is called from something that is exported (or `main()`). Note that it depends on the crate type what functions are exported: 1. For rlibs and dylibs everything that is reachable from the outside is exported. 2. For executables, cdylibs, and staticlibs, items are only exported if they are additionally `#[no_mangle]` or have an `#[export_name]`. The commits in this PR contain many examples of how tests can be updated to comply to the new requirements.
2017-11-08incr.comp.: Adapt nested_items test to new HIR hashing rules.Michael Woerister-18/+18
2017-11-08incr.comp.: Make DefSpan an input dep-node so it is not affected by the ↵Michael Woerister-7/+9
existing Span/HIR hashing hack.
2017-11-08Disable `mmap` in `libbacktrace` on Apple platformsJohn Colanduoni-0/+34
Fixes #45731 libbacktrace uses mmap if available to map ranges of the files containing debug information. On macOS `mmap` will succeed even if the mapped range does not exist, and a SIGBUS (with an unusual EXC_BAD_ACCESS code 10) will occur when the program attempts to page in the memory. To combat this we force `libbacktrace` to be built with the simple `read` based fallback on Apple platforms.
2017-11-08Update fastcall-inreg codegen test so that functions actually get instantiated.Michael Woerister-7/+7
2017-11-08Auto merge of #45862 - GuillaumeGomez:rollup, r=GuillaumeGomezbors-0/+59
Rollup of 4 pull requests - Successful merges: #45582, #45766, #45830, #45849 - Failed merges:
2017-11-08Auto merge of #45735 - tirr-c:issue-45730, r=arielb1bors-0/+51
Forbid casting to/from a pointer of unknown kind Fixes #45730. Before, it ICE'd when `pointer_kind` encountered `TyInfer`.
2017-11-07Add more elements in the sidebarGuillaume Gomez-0/+59
2017-11-07Make trans const eval error on overflow and NaN, matching HIR const eval.Robin Kruppe-39/+113
2017-11-07Saturating casts between integers and floats (both directions).Robin Kruppe-0/+206
This affects regular code generation as well as constant evaluation in trans, but not the HIR constant evaluator because that one returns an error for overflowing casts and NaN-to-int casts. That error is conservatively correct and we should be careful to not accept more code in constant expressions. The changes to code generation are guarded by a new -Z flag, to be able to evaluate the performance impact. The trans constant evaluation changes are unconditional because they have no run time impact and don't affect type checking either.
2017-11-07incr.comp.: Acknowledge the fact that shift operations can panic at runtime.Michael Woerister-2/+37
2017-11-07Rollup merge of #45784 - harpocrates:fix/print-parens-cast-lt, r=kennytmkennytm-0/+46
Pretty print parens around casts on the LHS of `<`/`<<` When pretty printing a cast expression occuring on the LHS of a `<` or `<<` expression, we should add parens around the cast. Otherwise, the `<`/`<<` gets interpreted as the beginning of the generics for the type on the RHS of the cast. Consider: $ cat parens_cast.rs macro_rules! negative { ($e:expr) => { $e < 0 } } fn main() { negative!(1 as i32); } Before this PR, the output of the following is not valid Rust: $ rustc -Z unstable-options --pretty=expanded parens_cast.rs #![feature(prelude_import)] #![no_std] #[prelude_import] use std::prelude::v1::*; #[macro_use] extern crate std as std; macro_rules! negative(( $ e : expr ) => { $ e < 0 }); fn main() { 1 as i32 < 0; } After this PR, the output of the following is valid Rust: $ rustc -Z unstable-options --pretty=expanded parens_cast.rs #![feature(prelude_import)] #![no_std] #[prelude_import] use std::prelude::v1::*; #[macro_use] extern crate std as std; macro_rules! negative(( $ e : expr ) => { $ e < 0 }); fn main() { (1 as i32) < 0; } I've gone through several README/wiki style documents but I'm still not sure where to test this though. I'm not even sure if this sort of thing is tested...
2017-11-07Rollup merge of #45764 - QuietMisdreavus:rustdoc-doctest-lints, r=GuillaumeGomezkennytm-4/+4
rustdoc: add #[allow(unused)] to every doctest More information in #45750 - this is behavior that was documented but not actually implemented. I also reordered how outer attributes are applied to doctests. Previously, attributes from `#![doc(test(attr(...)))]` would be applied *after* attributes from within the test itself, meaning if a doctest tried to override lints that would be set crate-wide, it wouldn't work at all. This gives a better scope of how lints can be applied. Closes #45750
2017-11-07Rollup merge of #45751 - estebank:issue-44684, r=nikomatsakiskennytm-12/+53
Handle anon lifetime arg being returned with named lifetime return type When there's a lifetime mismatch between an argument with an anonymous lifetime being returned in a method with a return type that has a named lifetime, show specialized lifetime error pointing at argument with a hint to give it an explicit lifetime matching the return type. ``` error[E0621]: explicit lifetime required in the type of `other` --> file2.rs:21:21 | 17 | fn bar(&self, other: Foo) -> Foo<'a> { | ----- consider changing the type of `other` to `Foo<'a>` ... 21 | other | ^^^^^ lifetime `'a` required ``` Follow up to #44124 and #42669. Fix #44684.
2017-11-07Fix some rebasing fallout.Michael Woerister-5/+8
2017-11-07Update run-make tests.Michael Woerister-2/+16
2017-11-07Update mir-opt tests.Michael Woerister-5/+20
2017-11-07Update compile-fail tests.Michael Woerister-33/+36
2017-11-07Update codegen tests.Michael Woerister-20/+20
2017-11-07Fix incremental tests after change to instantiation strategy.Michael Woerister-275/+285
2017-11-07Update invalid inline arg test.Michael Woerister-1/+3
2017-11-07Add regression tests for non-instantiation of inline and const fns.Michael Woerister-0/+45
2017-11-07Update codegen-unit tests.Michael Woerister-47/+47
2017-11-07Auto merge of #45620 - ollie27:rustdoc_impl_generic_dupe, r=QuietMisdreavusbors-0/+25
rustdoc: Fix duplicated impls with generics The same type can appear multiple times in impls so we need to use a set to avoid adding it multiple times. Fixes: #45584
2017-11-06Update comments in cast-lt.ppAlec Theriault-3/+1
2017-11-06review commentsEsteban Küber-2/+2
2017-11-06Auto merge of #45668 - nikomatsakis:nll-free-region, r=arielb1bors-0/+85
extend NLL with preliminary support for free regions on functions This PR extends https://github.com/rust-lang/rust/pull/45538 with support for free regions. This is pretty preliminary and will no doubt want to change in various ways, particularly as we add support for closures, but it's enough to get the basic idea in place: - We now create specific regions to represent each named lifetime declared on the function. - Region values can contain references to these regions (represented for now as a `BTreeSet<RegionIndex>`). - If we wind up trying to infer that `'a: 'b` must hold, but no such relationship was declared, we report an error. It also does a number of drive-by refactorings. r? @arielb1 cc @spastorino
2017-11-07Forbid casting to/from a pointer of unknown kindWonwoo Choi-0/+51
2017-11-06Auto merge of #45737 - oli-obk:json, r=petrochenkovbors-5/+383
Pretty print json in ui tests I found the json output in one line to not be useful for reviewing r? @petrochenkov
2017-11-06Adjust json errors to byte changesOliver Schneider-32/+32
2017-11-05Fix commentsAlec Theriault-3/+1
2017-11-05Added testsAlec Theriault-0/+50
2017-11-05Auto merge of #45723 - sinkuu:ice_45493, r=arielb1bors-0/+26
Fix MIR inlining panic in generic function MIR inlining calls `Instance::resolve` with a substs containing param, and `trans_apply_param_substs` panics. ~~This PR fixes it by making `Instance::resolve` return `None` if `substs.has_param_types()`, though I'm not sure if this is a right fix.~~ Fixes #45493.
2017-11-05Handle anon lifetime arg being returned with named lifetime return typeEsteban Küber-4/+45
When there's a lifetime mismatch between an argument with an anonymous lifetime being returned in a method with a return type that has a named lifetime, show specialized lifetime error pointing at argument with a hint to give it an explicit lifetime matching the return type. ``` error[E0621]: explicit lifetime required in the type of `other` --> file2.rs:21:21 | 17 | fn bar(&self, other: Foo) -> Foo<'a> { | ----- consider changing the type of `other` to `Foo<'a>` ... 21 | other | ^^^^^ lifetime `'a` required ``` Follow up to #44124 and #42669.
2017-11-05Auto merge of #45072 - nikomatsakis:issue-38714, r=arielb1bors-22/+442
new rules for merging expected and supplied types in closure signatures As uncovered in #38714, we currently have some pretty bogus code for combining the "expected signature" of a closure with the "supplied signature". To set the scene, consider a case like this: ```rust fn foo<F>(f: F) where F: for<'a> FnOnce(&'a u32) -> &'a u32 // ^ *expected* signature comes from this where-clause { ... } fn main() { foo(|x: &u32| -> &u32 { .. } // ^^^^^^^^^^^^^^^^^ supplied signature // comes from here } ``` In this case, the supplied signature (a) includes all the parts and (b) is the same as the expected signature, modulo the names used for the regions. But often people supply only *some* parts of the signature. For example, one might write `foo(|x| ..)`, leaving *everything* to be inferred, or perhaps `foo(|x: &u32| ...)`, which leaves the return type to be inferred. In the current code, we use the expected type to supply the types that are not given, but otherwise use the type the user gave, except for one case: if the user writes `fn foo(|x: _| ..)` (i.e., an underscore at the outermost level), then we will take the expected type (rather than instantiating a fresh type variable). This can result in nonsensical situations, particularly with bound regions that link the types of parameters to one another or to the return type. Consider `foo(|x: &u32| ...)` -- if we *literally* splice the expected return type of `&'a u32` together with what the user gave, we wind up with a signature like `for<'a> fn(&u32) -> &'a u32`. This is not even permitted as a type, because bound regions like `'a` must appear also in the arguments somewhere, which is why #38714 leads to an ICE. This PR institutes some new rules. These are not meant to be the *final* set of rules, but they are a kind of "lower bar" for what kind of code we accept (i.e., we can extend these rules in the future to be smarter in some cases, but -- as we will see -- these rules do accept some things that we then would not be able to back off from). These rules are derived from a few premises: - First and foremost, anonymous regions in closure annotation are mostly requests for the code to "figure out the right lifetime" and shouldn't be read too closely. So for example when people write a closure signature like `|x: &u32|`, they are really intended for us to "figure out" the right region for `x`. - In contrast, the current code treats this supplied type as being more definitive. In particular, writing `|x: &u32|` would always result in the region of `x` being bound in the closure type. In other words, the signature would be something like `for<'a> fn(&'a u32)` -- this is derived from the fact that `fn(&u32)` expands to a type where the region is bound in the fn type. - This PR takes a different approach. The "binding level" for reference types appearing in closure signatures can be informed in some cases by the expected signature. So, for example, if the expected signature is something like `(&'f u32)`, where the region of the first argument appears free, then for `|x: &u32|`, the new code would infer `x` to also have the free region `'f`. - This inference has some limits. We don't do this for bindings that appear within the selected types themselves. So e.g. `|x: fn(&u32)|`, when combined with an expected type of `fn(fn(&'f u32))`, would still result in a closure that expects `for<'a> fn(&'a u32)`. Such an annotation will ultimately result in an error, as it happens, since `foo` is supplying a `fn(&'f u32)` to the closure, but the closure signature demands a `for<'a> fn(&'a u32)`. But still we choose to trust it and have the user change it. - I wanted to preserve the rough intuition that one can copy-and-paste a type out of the fn signature and into the fn body without dramatically changing its meaning. Interestingly, if one has `|x: &u32|`, then regardless of whether the region of `x` is bound or free in the closure signature, it is also free in the region body, and that is also true when one writes `let x: &u32`, so that intuition holds here. But the same would not be true for `fn(&u32)`, hence the different behavior. - Second, we must take either **all** the references to bound regions from the expected type or **none**. The current code, as we saw, will happily take a bound region in the return type but drop the other place where it is used, in the parameters. Since bound regions are all about linking multiple things together, I think it's important not to do that. (That said, we could conceivably be a bit less strict here, since the subtyping rules will get our back, but we definitely don't want any bound regions that appear only in the return type.) - Finally, we cannot take the bound region names from the supplied types and "intermix" them with the names from the expected types. - We *could* potentially do some alpha renaming, but I didn't do that. - Ultimately, if the types the user supplied do not match expectations in some way that we cannot recover from, we fallback to deriving the closure signature solely from those expected types. - For example, if the expected type is `u32` but the user wrote `i32`. - Or, more subtle, if the user wrote e.g. `&'x u32` for some named lifetime `'x`, but the expected type includes a bound lifetime (`for<'a> (&'a u32)`). In that case, preferring the type that the user explicitly wrote would hide an appearance of a bound name from the expected type, and we try to never do that. The detailed rules that I came up with are found in the code, but for ease of reading I've also [excerpted them into a gist](https://gist.github.com/nikomatsakis/e69252a2b57e6d97d044c2f254c177f1). I am not convinced they are correct and would welcome feedback for alternative approaches. (As an aside, the way I think I would ultimately *prefer* to think about this is that the conversion from HIR types to internal types could be parameterized by an "expected type" that it uses to guide itself. However, since that would be a pain, I opted *in the code* to first instantiate the supplied types as `Ty<'tcx>` and then "merge" those types with the `Ty<'tcx>` from the expected signature.) I think we should probably FCP this before landing. cc @rust-lang/lang r? @arielb1
2017-11-05add #![allow(unused)] to the playground link rustdoc testsQuietMisdreavus-4/+4
2017-11-05Fix MIR inlining panic in generic functionsinkuu-0/+26
2017-11-05Auto merge of #44042 - LukasKalbertodt:ascii-methods-on-instrinsics, ↵bors-2/+2
r=alexcrichton Copy all `AsciiExt` methods to the primitive types directly in order to deprecate it later **EDIT:** [this PR is ready now](https://github.com/rust-lang/rust/pull/44042#issuecomment-333883548). I edited this post to reflect the current status of discussion, which is (apart from code review) pretty much settled. --- This is my current progress in order to prepare stabilization of #39658. As discussed there (and in #39659), the idea is to deprecated `AsciiExt` and copy all methods to the type directly. Apparently there isn't really a reason to have those methods in an extension trait¹. ~~This is **work in progress**: copy&pasting code while slightly modifying the documentation isn't the most exciting thing to do. Therefore I wanted to already open this WIP PR after doing basically 1/4 of the job (copying methods to `&[u8]`, `char` and `&str` is still missing) to get some feedback before I continue. Some questions possibly worth discussing:~~ 1. ~~Does everyone agree that deprecating `AsciiExt` is a good idea? Does everyone agree with the goal of this PR?~~ => apparently yes 2. ~~Are my changes OK so far? Did I do something wrong?~~ 3. ~~The issue of the unstable-attribute is currently set to 0. I would wait until you say "Ok" to the whole thing, then create a tracking issue and then insert the correct issue id. Is that ok?~~ 4. ~~I tweaked `eq_ignore_ascii_case()`: it now takes the argument `other: u8` instead of `other: &u8`. The latter was enforced by the trait. Since we're not bound to a trait anymore, we can drop the reference, ok?~~ => I reverted this, because the interface has to match the `AsciiExt` interface exactly. ¹ ~~Could it be that we can't write `impl [u8] {}`? This might be the reason for `AsciiExt`. If that is the case: is there a good reason we can't write such an impl block? What can we do instead?~~ => we couldn't at the time this PR was opened, but Simon made it possible. /cc @SimonSapin @zackw
2017-11-05Auto merge of #45754 - scottmcm:checked-npot, r=dtolnaybors-0/+60
Fix #18604: next_power_of_two should panic on overflow Fixes https://github.com/rust-lang/rust/issues/18604 Is it possible to write a test for this? My experiments showed `x.py test` running in release mode, so my attempt at a `#[should_panic]` didn't work.
2017-11-05Auto merge of #45748 - petrochenkov:short, r=alexcrichtonbors-1/+1
Shorten paths to auxiliary files created by tests I'm hitting issues with long file paths to object files created by the test suite, similar to https://github.com/rust-lang/rust/issues/45103#issuecomment-335622075. If we look at the object file path in https://github.com/rust-lang/rust/issues/45103 we can see that the patch contains of few components: ``` specialization-cross-crate-defaults.stage2-x86_64-pc-windows-gnu.run-pass.libaux\specialization_cross_crate_defaults.specialization_cross_crate_defaults0.rust-cgu.o ``` => 1. specialization-cross-crate-defaults // test name, required 2. stage2 // stage disambiguator, required 3. x86_64-pc-windows-gnu // target disambiguator, required 4. run-pass // mode disambiguator, rarely required 5. libaux // suffix, can be shortened 6. specialization_cross_crate_defaults // required, there may be several libraries in the directory 7. specialization_cross_crate_defaults0 // codegen unit name, can be shortened? 8. rust-cgu // suffix, can be shortened? 9. o // object file extension This patch addresses items `4`, `5` and `8`. `libaux` is shortened to `aux`, `rust-cgu` is shortened to `rcgu`, mode disambiguator is omitted unless it's necessary (for pretty-printing and debuginfo tests, see https://github.com/rust-lang/rust/pull/24537/commits/38d26d811a44ba93637c84ce77a58af88c47f0ac) I haven't touched names of codegen units though (`specialization_cross_crate_defaults0`). Is it useful for them to have descriptive names including the crate name, as opposed to just `0` or `cgu0` or something?
2017-11-04rustc: Handle some libstd symbole exports betterAlex Crichton-0/+33
Right now symbol exports, particularly in a cdylib, are handled by assuming that `pub extern` combined with `#[no_mangle]` means "export this". This isn't actually what we want for some symbols that the standard library uses to implement itself, for example symbols related to allocation. Additionally other special symbols like `rust_eh_personallity` have no need to be exported from cdylib crate types (only needed in dylib crate types). This commit updates how rustc handles these special symbols by adding to the hardcoded logic of symbols like `rust_eh_personallity` but also adding a new attribute, `#[rustc_std_internal_symbol]`, which forces the export level to be considered the same as all other Rust functions instead of looking like a C function. The eventual goal here is to prevent functions like `__rdl_alloc` from showing up as part of a Rust cdylib as it's just an internal implementation detail. This then further allows such symbols to get gc'd by the linker when creating a cdylib.
2017-11-04Auto merge of #45711 - tirr-c:unicode-span, r=estebankbors-2/+67
Display spans correctly when there are zero-width or wide characters Hopefully... * fixes #45211 * fixes #8706 --- Before: ``` error: invalid width `7` for integer literal --> unicode_2.rs:12:25 | 12 | let _ = ("a̐éö̲", 0u7); | ^^^ | = help: valid widths are 8, 16, 32, 64 and 128 error: invalid width `42` for integer literal --> unicode_2.rs:13:20 | 13 | let _ = ("아あ", 1i42); | ^^^^ | = help: valid widths are 8, 16, 32, 64 and 128 error: aborting due to 2 previous errors ``` After: ``` error: invalid width `7` for integer literal --> unicode_2.rs:12:25 | 12 | let _ = ("a̐éö̲", 0u7); | ^^^ | = help: valid widths are 8, 16, 32, 64 and 128 error: invalid width `42` for integer literal --> unicode_2.rs:13:20 | 13 | let _ = ("아あ", 1i42); | ^^^^ | = help: valid widths are 8, 16, 32, 64 and 128 error: aborting due to 2 previous errors ``` Spans might display incorrectly on the browser. r? @estebank