Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 11 pull requests #70202

Closed
wants to merge 52 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
57b1e7a
Remove the call that makes miri fail
DutchGhost Mar 16, 2020
dcc2321
The const_forget_box was unused, and doesns't add anything to test by…
DutchGhost Mar 16, 2020
0760803
rather than removing const_forget_box, stick an attribute on it and e…
DutchGhost Mar 16, 2020
a5206f9
add `Option::{zip,zip_with}` methods under "option_zip" gate
WaffleLapkin Mar 13, 2020
d36d3fa
fixes to `Option::{zip,zip_with}`
WaffleLapkin Mar 18, 2020
4c363e3
Move the const-forget test into ui tests
DutchGhost Mar 18, 2020
6c37252
permit negative impls for non-auto traits
nikomatsakis Jan 8, 2020
f1b86fc
make a custom error for overlap with negative impls
nikomatsakis Jan 8, 2020
a781991
introduce `negative_impls` feature gate and document
nikomatsakis Jan 9, 2020
9312607
create a tracking issue and link to it
nikomatsakis Jan 17, 2020
c5b01fd
bump negative impls version to 1.44.0
nikomatsakis Mar 13, 2020
eb3bcf8
convert to doc comments
nikomatsakis Mar 13, 2020
30e73e6
move feature-gate-negative-impls test to traits/negative-impls
nikomatsakis Mar 13, 2020
1868640
comment the `typeck-negative-impls-builtin` test
nikomatsakis Mar 13, 2020
09f1e6a
give the negative-impls-builtin test a more sensible name
nikomatsakis Mar 13, 2020
377835e
move stderr file too
nikomatsakis Mar 13, 2020
d3866a4
add test for negative specializes negative
nikomatsakis Mar 13, 2020
e6db481
use slice pattern instead of calling `is_empty()` and `[0]`
nikomatsakis Mar 19, 2020
62d46f8
pacify the merciless x.py fmt
nikomatsakis Mar 19, 2020
121bffc
make "other" in docs of `Option::{zip,zip_with}` monofont
WaffleLapkin Mar 19, 2020
bd6deaa
Derive PartialEq, Eq and Hash for RangeInclusive
Mar 19, 2020
6570e27
Removed unused `Hasher` import.
Mar 19, 2020
fd0e15b
Make std::sync::Arc compatible with ThreadSanitizer
tmiasko Mar 20, 2020
d6f3a43
Update const_forget.rs
DutchGhost Mar 20, 2020
3f6236e
Fix oudated comment for NamedRegionMap
bjorn3 Mar 20, 2020
e61f126
Replace shared root with optional root
Mark-Simulacrum Mar 18, 2020
1c44f85
Remove shared root code and assertions from BTree nodes
Mark-Simulacrum Mar 18, 2020
3c04fda
Make functions dependent only on shared root avoidance safe
Mark-Simulacrum Mar 18, 2020
54b7c38
Drop NodeHeader type from BTree code
Mark-Simulacrum Mar 18, 2020
13f6d77
Simplify ensure_root_is_owned callers
Mark-Simulacrum Mar 18, 2020
4d85314
Update test commentary for shared root removal
Mark-Simulacrum Mar 20, 2020
bce7f6f
Fix debugger pretty printing of BTrees
Mark-Simulacrum Mar 18, 2020
32670dd
Clean up E0439 explanation
GuillaumeGomez Mar 20, 2020
0296d49
fix layout_test visitor name
RalfJung Mar 10, 2020
55c2cf2
add debug option to #[rustc_layout]
RalfJung Mar 10, 2020
d9f60bc
add a test for rustc_layout(debug)
RalfJung Mar 10, 2020
0d018a5
expand_include: set `.directory` to dir of included file.
Centril Mar 20, 2020
c62e36b
make rustc_layout also work for type definitions
RalfJung Mar 20, 2020
951a366
remove redundant import (clippy::single_component_path_imports)
matthiaskrgr Mar 19, 2020
ad00e91
remove redundant returns (clippy::needless_return)
matthiaskrgr Mar 20, 2020
7b49678
fmt
RalfJung Mar 20, 2020
111301d
Rollup merge of #65097 - tmiasko:arc, r=Amanieu
Dylan-DPC Mar 21, 2020
16338b1
Rollup merge of #68004 - nikomatsakis:negative-impls, r=varkor
Dylan-DPC Mar 21, 2020
c31cd0f
Rollup merge of #69901 - RalfJung:rustc_layout, r=eddyb
Dylan-DPC Mar 21, 2020
63ceb8e
Rollup merge of #69997 - WaffleLapkin:option_zip, r=LukasKalbertodt
Dylan-DPC Mar 21, 2020
0751e6a
Rollup merge of #70038 - DutchGhost:const-forget-tests, r=RalfJung
Dylan-DPC Mar 21, 2020
1bdc860
Rollup merge of #70111 - Mark-Simulacrum:btree-no-shared, r=cuviper
Dylan-DPC Mar 21, 2020
be6e983
Rollup merge of #70166 - CDirkx:range-inclusive-derives, r=cramertj
Dylan-DPC Mar 21, 2020
8ce4c1c
Rollup merge of #70177 - bjorn3:patch-2, r=Dylan-DPC
Dylan-DPC Mar 21, 2020
c4494c8
Rollup merge of #70184 - Centril:include-mod-relativism, r=petrochenkov
Dylan-DPC Mar 21, 2020
b20db78
Rollup merge of #70187 - matthiaskrgr:cl2ppy, r=Mark-Simulacrum
Dylan-DPC Mar 21, 2020
cb62d67
Rollup merge of #70188 - GuillaumeGomez:cleanup-e0439, r=Dylan-DPC
Dylan-DPC Mar 21, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions src/doc/unstable-book/src/language-features/negative-impls.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# `negative_impls`

The tracking issue for this feature is [#68318].

[#68318]: https://github.com/rust-lang/rust/issues/68318

----

With the feature gate `negative_impls`, you can write negative impls as well as positive ones:

```rust
#![feature(negative_impls)]
trait DerefMut { }
impl<T: ?Sized> !DerefMut for &T { }
```

Negative impls indicate a semver guarantee that the given trait will not be implemented for the given types. Negative impls play an additional purpose for auto traits, described below.

Negative impls have the following characteristics:

* They do not have any items.
* They must obey the orphan rules as if they were a positive impl.
* They cannot "overlap" with any positive impls.

## Semver interaction

It is a breaking change to remove a negative impl. Negative impls are a commitment not to implement the given trait for the named types.

## Orphan and overlap rules

Negative impls must obey the same orphan rules as a positive impl. This implies you cannot add a negative impl for types defined in upstream crates and so forth.

Similarly, negative impls cannot overlap with positive impls, again using the same "overlap" check that we ordinarily use to determine if two impls overlap. (Note that positive impls typically cannot overlap with one another either, except as permitted by specialization.)

## Interaction with auto traits

Declaring a negative impl `impl !SomeAutoTrait for SomeType` for an
auto-trait serves two purposes:

* as with any trait, it declares that `SomeType` will never implement `SomeAutoTrait`;
* it disables the automatic `SomeType: SomeAutoTrait` impl that would otherwise have been generated.

Note that, at present, there is no way to indicate that a given type
does not implement an auto trait *but that it may do so in the
future*. For ordinary types, this is done by simply not declaring any
impl at all, but that is not an option for auto traits. A workaround
is that one could embed a marker type as one of the fields, where the
marker type is `!AutoTrait`.

## Immediate uses

Negative impls are used to declare that `&T: !DerefMut` and `&mut T: !Clone`, as required to fix the soundness of `Pin` described in [#66544](https://github.com/rust-lang/rust/issues/66544).

This serves two purposes:

* For proving the correctness of unsafe code, we can use that impl as evidence that no `DerefMut` or `Clone` impl exists.
* It prevents downstream crates from creating such impls.
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ The `optin_builtin_traits` feature gate allows you to define auto traits.

Auto traits, like [`Send`] or [`Sync`] in the standard library, are marker traits
that are automatically implemented for every type, unless the type, or a type it contains,
has explicitly opted out via a negative impl.
has explicitly opted out via a negative impl. (Negative impls are separately controlled
by the `negative_impls` feature.)

[`Send`]: https://doc.rust-lang.org/std/marker/trait.Send.html
[`Sync`]: https://doc.rust-lang.org/std/marker/trait.Sync.html
Expand All @@ -22,6 +23,7 @@ impl !Type for Trait
Example:

```rust
#![feature(negative_impls)]
#![feature(optin_builtin_traits)]

auto trait Valid {}
Expand All @@ -43,3 +45,63 @@ fn main() {
// must_be_valid( MaybeValid(False) );
}
```

## Automatic trait implementations

When a type is declared as an `auto trait`, we will automatically
create impls for every struct/enum/union, unless an explicit impl is
provided. These automatic impls contain a where clause for each field
of the form `T: AutoTrait`, where `T` is the type of the field and
`AutoTrait` is the auto trait in question. As an example, consider the
struct `List` and the auto trait `Send`:

```rust
struct List<T> {
data: T,
next: Option<Box<List<T>>>,
}
```

Presuming that there is no explicit impl of `Send` for `List`, the
compiler will supply an automatic impl of the form:

```rust
struct List<T> {
data: T,
next: Option<Box<List<T>>>,
}

unsafe impl<T> Send for List<T>
where
T: Send, // from the field `data`
Option<Box<List<T>>>: Send, // from the field `next`
{ }
```

Explicit impls may be either positive or negative. They take the form:

```rust,ignore
impl<...> AutoTrait for StructName<..> { }
impl<...> !AutoTrait for StructName<..> { }
```

## Coinduction: Auto traits permit cyclic matching

Unlike ordinary trait matching, auto traits are **coinductive**. This
means, in short, that cycles which occur in trait matching are
considered ok. As an example, consider the recursive struct `List`
introduced in the previous section. In attempting to determine whether
`List: Send`, we would wind up in a cycle: to apply the impl, we must
show that `Option<Box<List>>: Send`, which will in turn require
`Box<List>: Send` and then finally `List: Send` again. Under ordinary
trait matching, this cycle would be an error, but for an auto trait it
is considered a successful match.

## Items

Auto traits cannot have any trait items, such as methods or associated types. This ensures that we can generate default implementations.

## Supertraits

Auto traits cannot have supertraits. This is for soundness reasons, as the interaction of coinduction with implied bounds is difficult to reconcile.

34 changes: 21 additions & 13 deletions src/etc/gdb_rust_pretty_printing.py
Original file line number Diff line number Diff line change
Expand Up @@ -370,12 +370,17 @@ def to_string(self):
("(len: %i)" % self.__val.get_wrapped_value()['map']['length']))

def children(self):
root = self.__val.get_wrapped_value()['map']['root']
node_ptr = root['node']
i = 0
for child in children_of_node(node_ptr, root['height'], False):
yield (str(i), child)
i = i + 1
prev_idx = None
innermap = GdbValue(self.__val.get_wrapped_value()['map'])
if innermap.get_wrapped_value()['length'] > 0:
root = GdbValue(innermap.get_wrapped_value()['root'])
type_name = str(root.type.ty.name).replace('core::option::Option<', '')[:-1]
root = root.get_wrapped_value().cast(gdb.lookup_type(type_name))
node_ptr = root['node']
i = 0
for child in children_of_node(node_ptr, root['height'], False):
yield (str(i), child)
i = i + 1


class RustStdBTreeMapPrinter(object):
Expand All @@ -391,13 +396,16 @@ def to_string(self):
("(len: %i)" % self.__val.get_wrapped_value()['length']))

def children(self):
root = self.__val.get_wrapped_value()['root']
node_ptr = root['node']
i = 0
for child in children_of_node(node_ptr, root['height'], True):
yield (str(i), child[0])
yield (str(i), child[1])
i = i + 1
if self.__val.get_wrapped_value()['length'] > 0:
root = GdbValue(self.__val.get_wrapped_value()['root'])
type_name = str(root.type.ty.name).replace('core::option::Option<', '')[:-1]
root = root.get_wrapped_value().cast(gdb.lookup_type(type_name))
node_ptr = root['node']
i = 0
for child in children_of_node(node_ptr, root['height'], True):
yield (str(i), child[0])
yield (str(i), child[1])
i = i + 1


class RustStdStringPrinter(object):
Expand Down
Loading