Skip to content

Commit

Permalink
Merge branch 'nightly' into refactor-string-stringslice-constructor
Browse files Browse the repository at this point in the history
  • Loading branch information
martinvuyk authored Dec 16, 2024
2 parents b1f6248 + 9f4544a commit 75c2215
Show file tree
Hide file tree
Showing 33 changed files with 3,520 additions and 3,407 deletions.
893 changes: 469 additions & 424 deletions docs/changelog-released.md

Large diffs are not rendered by default.

55 changes: 55 additions & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,66 @@ what we publish.

### Standard library changes

- `UnsafePointer` is now parameterized on mutability. Previously,
`UnsafePointer` could only represent mutable pointers.

The new `mut` parameter can be used to restrict an `UnsafePointer` to a
specific mutability: `UnsafePointer[T, mut=False]` represents a pointer to
an immutable `T` value. This is analogous to a `const *` pointer in C++.

- `UnsafePointer.address_of()` will now infer the origin and mutability
of the resulting pointer from the argument. For example:

```mojo
var local = 10
# Constructs a mutable pointer, because `local` is a mutable memory location
var ptr = UnsafePointer.address_of(local)
```
To force the construction of an immutable pointer to an otherwise mutable
memory location, use a cast:
```mojo
var local = 10
# Cast the mutable pointer to be immutable.
var ptr = UnsafePointer.address_of(local).bitcast[mut=False]()
```
- The `unsafe_ptr()` method on several standard library collection types have
been updated to use parametric mutability: they will return an `UnsafePointer`
whose mutability is inherited from the mutability of the `ref self` of the
receiver at the call site. For example, `ptr1` will be immutable, while
`ptr2` will be mutable:
```mojo
fn take_lists(read list1: List[Int], mut list2: List[Int]):
# Immutable pointer, since receiver is immutable `read` reference
var ptr1 = list1.unsafe_ptr()
# Mutable pointer, since receiver is mutable `mut` reference
var ptr2 = list2.unsafe_ptr()
```
### Tooling changes
- mblack (aka `mojo format`) no longer formats non-mojo files. This prevents
unexpected formatting of python files.
- Full struct signature information is now exposed in the documentation
generator, and in the symbol outline and hover markdown via the Mojo Language
Server.
### ❌ Removed
- `StringRef` is being deprecated. Use `StringSlice` instead.
- removed `StringRef.startswith()` and `StringRef.endswith()`
### 🛠️ Fixed
- The Mojo Kernel for Jupyter Notebooks is working again on nightly releases.
- The command `mojo debug --vscode` now sets the current working directory
properly.
- The Mojo Language Server doesn't crash anymore on empty **init**.mojo files.
[Issue #3826](https://github.com/modularml/mojo/issues/3826).
2 changes: 1 addition & 1 deletion docs/manual/functions.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -552,7 +552,7 @@ Thus, you can also pass a `StringLiteral` to a function that expects a `String`.
When resolving an overloaded function call, the Mojo compiler tries each
candidate function and uses the one that works (if only one version works), or
it picks the closest match (if it can determine a close match), or it reports
that the call is ambiguous (if it cant figure out which one to pick).
that the call is ambiguous (if it can't figure out which one to pick).

If the compiler can't figure out which function to use, you can resolve the
ambiguity by explicitly casting your value to a supported argument type. For
Expand Down
6 changes: 3 additions & 3 deletions docs/manual/lifecycle/death.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ the end of the code scope to destroy values):
because the destructor call always happens before the tail call.

Additionally, Mojo's ASAP destruction works great within Python-style `def`
functions. That's because Python doesnt really provide scopes beyond a
functions. That's because Python doesn't really provide scopes beyond a
function scope, so the Python garbage collector cleans up resources more often
than a scope-based destruction policy would. However, Mojo does not use a
garbage collector, so the ASAP destruction policy provides destruction
Expand Down Expand Up @@ -276,7 +276,7 @@ object.

Mojo's policy here is powerful and intentionally straight-forward: fields can
be temporarily transferred, but the "whole object" must be constructed with the
aggregate types initializer and destroyed with the aggregate destructor. This
aggregate type's initializer and destroyed with the aggregate destructor. This
means it's impossible to create an object by initializing only its fields, and
it's likewise impossible to destroy an object by destroying only its fields.

Expand Down Expand Up @@ -316,7 +316,7 @@ to a new instance (read more about the [move
constructor](/mojo/manual/lifecycle/life#move-constructor)),
while `__del__()` implements the deletion logic for its `self`. As such, they
both need to own and transform elements of the `owned` value, and they
definitely dont want the original `owned` value's destructor to also run—that
definitely don't want the original `owned` value's destructor to also run—that
could result in a double-free error, and in the case of the `__del__()` method,
it would become an infinite loop.

Expand Down
2 changes: 1 addition & 1 deletion docs/manual/lifecycle/life.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -656,7 +656,7 @@ things like a single integer or floating point number. We call these types
and destroyed without invoking any custom lifecycle methods.

Trivial types are the most common types that surround us, and from a language
perspective, Mojo doesnt need special support for these written in a struct.
perspective, Mojo doesn't need special support for these written in a struct.
Usually, these values are so tiny that they should be passed around in CPU
registers, not indirectly through memory.

Expand Down
30 changes: 15 additions & 15 deletions docs/manual/pointers/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ print(ptr[])

## Pointer terminology

Before we jump into the pointer types, here are a few terms youll run across. Some
Before we jump into the pointer types, here are a few terms you'll run across. Some
of them may already be familiar to you.

- **Safe pointers**: are designed to prevent memory errors. Unless you use one
Expand All @@ -54,7 +54,7 @@ of them may already be familiar to you.
use-after-free.

- **Nullable pointers**: can point to an invalid memory location (typically 0,
or a “null pointer”). Safe pointers arent nullable.
or a “null pointer”). Safe pointers aren't nullable.

- **Smart pointers**: own their pointees, which means that the value they point
to may be deallocated when the pointer itself is destroyed. Non-owning
Expand All @@ -66,10 +66,10 @@ or a “null pointer”). Safe pointers aren’t nullable.
allocation can either be implicit (that is, performed automatically when
initializing a pointer with a value) or explicit.

- **Uninitialized memory**: refers to memory locations that havent been
- **Uninitialized memory**: refers to memory locations that haven't been
initialized with a value, which may therefore contain random data.
Newly-allocated memory is uninitialized. The safe pointer types dont allow
users to access memory thats uninitialized. Unsafe pointers can allocate a
Newly-allocated memory is uninitialized. The safe pointer types don't allow
users to access memory that's uninitialized. Unsafe pointers can allocate a
block of uninitialized memory locations and then initialize them one at a time.
Being able to access uninitialized memory is unsafe by definition.

Expand All @@ -93,7 +93,7 @@ The Mojo standard library includes several pointer types with different
characteristics:

- [`Pointer`](/mojo/stdlib/memory/pointer/Pointer) is a safe pointer that points
to a single value that it doesnt own.
to a single value that it doesn't own.

- [`OwnedPointer`](/mojo/stdlib/memory/owned_pointer/OwnedPointer) is a smart
pointer that points to a single value, and maintains exclusive ownership of
Expand Down Expand Up @@ -139,10 +139,10 @@ The following sections provide more details on each pointer type.
## `Pointer`

The [`Pointer`](/mojo/stdlib/memory/pointer/Pointer) type is a safe pointer that
points to a initialized value that it doesnt own. Some example use cases for a
points to a initialized value that it doesn't own. Some example use cases for a
`Pointer` include:

- Storing a reference to a related type. For example, a lists iterator object
- Storing a reference to a related type. For example, a list's iterator object
might hold a `Pointer` back to the original list.

- Passing the memory location for a single value to external code via
Expand Down Expand Up @@ -181,11 +181,11 @@ either `Movable`, `Copyable`, or `ExplicitlyCopyable`.
Since an `OwnedPointer` is designed to enforce single ownership, the pointer
itself can be moved, but not copied.

Note: Currently, you cant create an `Optional[OwnedPointer[T]]` because the
Note: Currently, you can't create an `Optional[OwnedPointer[T]]` because the
`Optional` type only works with types that are both movable and copyable. This
restricts some use cases that would otherwise be a natural fit
for`OwnedPointer`, including self-referential data structures like linked lists
and trees. (Until this use case is supported for `OwnedPointer`, its possible
and trees. (Until this use case is supported for `OwnedPointer`, it's possible
to use`ArcPointer` where you need a smart pointer that can be `Optional`.)

## `ArcPointer`
Expand Down Expand Up @@ -241,19 +241,19 @@ def main():
Note: The reference count is stored using an
[`Atomic`]([/mojo/stdlib/os/atomic/Atomic](https://docs.modular-staging.com/mojo/stdlib/os/atomic/Atomic))
value to ensure that updates to the reference count are thread-safe. However,
Mojo doesnt currently enforce exclusive access across thread boundaries, so
its possible to form race conditions.
Mojo doesn't currently enforce exclusive access across thread boundaries, so
it's possible to form race conditions.

## UnsafePointer

[`UnsafePointer`](/mojo/stdlib/memory/unsafe_pointer/UnsafePointer) is a
low-level pointer that can access a block of contiguous memory locations, which
might be uninitialized. Its analogous to a raw pointer in the C and C++
might be uninitialized. It's analogous to a raw pointer in the C and C++
programming languages. `UnsafePointer` provides unsafe methods for initializing
and destroying stored values, as well as for accessing the values once theyre
and destroying stored values, as well as for accessing the values once they're
initialized.

As the name suggests, `UnsafePointer` doesnt provide any memory safety
As the name suggests, `UnsafePointer` doesn't provide any memory safety
guarantees, so you should reserve it for cases when none of the other pointer
types will do the job. Here are some use cases where you might want to use an
`UnsafePointer`:
Expand Down
8 changes: 4 additions & 4 deletions docs/manual/structs.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -195,15 +195,15 @@ Syntactically, the biggest difference compared to a Python class is that all
fields in a struct must be explicitly declared with `var`.

In Mojo, the structure and contents of a struct are set at compile time and
cant be changed while the program is running. Unlike in Python, where you can
add, remove, or change attributes of an object on the fly, Mojo doesnt allow
can't be changed while the program is running. Unlike in Python, where you can
add, remove, or change attributes of an object on the fly, Mojo doesn't allow
that for structs.

However, the static nature of structs helps Mojo run your code faster. The
program knows exactly where to find the structs information and how to use it
program knows exactly where to find the struct's information and how to use it
without any extra steps or delays at runtime.

Mojos structs also work really well with features you might already know from
Mojo's structs also work really well with features you might already know from
Python, like operator overloading (which lets you change how math symbols like
`+` and `-` work with your own data, using [special
methods](#special-methods)).
Expand Down
2 changes: 1 addition & 1 deletion docs/manual/types.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ There are a some types that aren't defined as structs:
signal "no value."

Mojo comes with a standard library that provides a number of useful types and
utility functions. These standard types arent privileged. Each of the standard
utility functions. These standard types aren't privileged. Each of the standard
library types is defined just like user-defined types—even basic types like
[`Int`](/mojo/stdlib/builtin/int/Int) and
[`String`](/mojo/stdlib/collections/string/String). But these standard library
Expand Down
2 changes: 1 addition & 1 deletion docs/tools/debugging.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ The debugger currently has the following limitations:

* When stepping out of a function, the returned value is not displayed.

* LLDB doesnt support stopping or resuming individual threads.
* LLDB doesn't support stopping or resuming individual threads.

### Breakpoints

Expand Down
8 changes: 4 additions & 4 deletions docs/tools/testing.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ consists of a set of assertions defined as part of the

## Get started

Lets start with a simple example of writing and running Mojo tests.
Let's start with a simple example of writing and running Mojo tests.

### 1. Write tests

Expand Down Expand Up @@ -106,7 +106,7 @@ its error message.

The Mojo standard library includes a [`testing`](/mojo/stdlib/testing/testing/)
module that defines several assertion functions for implementing tests. Each
assertion returns `None` if its condition is met or raises an error if it isnt.
assertion returns `None` if its condition is met or raises an error if it isn't.

* [`assert_true()`](/mojo/stdlib/testing/testing/assert_true):
Asserts that the input value is `True`.
Expand Down Expand Up @@ -597,8 +597,8 @@ a += 1

Test suite scopes do *not* nest. In other words, the test suite scope of a
module is completely independent of the test suite scope of a function or struct
defined within that module. For example, this means that if a modules test
suite creates a variable, that variable is *not* accessible to a functions test
defined within that module. For example, this means that if a module's test
suite creates a variable, that variable is *not* accessible to a function's test
suite within the same module.

:::
Expand Down
Loading

0 comments on commit 75c2215

Please sign in to comment.