C++ has had smart pointers for memory (and other resource) management for a long time now (see e.g. the Windows ATL classes for working with COM objects and resources).
There are a number of challenges that make browsers more challenging (even in memory safe languages like Swift and Rust).
1. Back references/pointers like `parentElement` to other objects in the graph that create dependency cycles (where traditional/simple reference counting will prevent the objects being deallocated).
2. Interacting with (and creating resources in) a garbage collector when running/evaluating JavaScript code.
3. Just-in-Time (JIT) compilation of JavaScript and other complicated interpretation-compilation pipelines that can allocate and transfer objects between the different stages.
Actually, if you implement a JavaScript runtime at all your choice is either too slow for modern web users or `unsafe` everywhere. Runtime values are often simultaneously either words that encode immediates or pointers to heap blocks and doing this the proper way blows up time and space. Doing it the fast way means you have `unsafe` everywhere and Rust's lifetime model can't help you at all. Everyone chooses the fast way.
Maybe Rust let's you encapsulate the unsafe a little better than C++ but the wins are going to be surprisingly small. If you had to build it today you'd maybe use Rust but the case for rewriting an existing C based runtime in Rust is not that strong.
Also for things like interpreter loops the absence of computed goto in Rust stable is a real performance killer. Explicit tail calls (the `become` keyword in nightly) work but maybe you don't want your big rewrite to rely on that.
There are a number of challenges that make browsers more challenging (even in memory safe languages like Swift and Rust).
1. Back references/pointers like `parentElement` to other objects in the graph that create dependency cycles (where traditional/simple reference counting will prevent the objects being deallocated).
2. Interacting with (and creating resources in) a garbage collector when running/evaluating JavaScript code.
3. Just-in-Time (JIT) compilation of JavaScript and other complicated interpretation-compilation pipelines that can allocate and transfer objects between the different stages.