Skip to content

Commit 8590501

Browse files
committed
Add E0270
1 parent 4337e82 commit 8590501

File tree

1 file changed

+87
-17
lines changed

1 file changed

+87
-17
lines changed

src/librustc/diagnostics.rs

Lines changed: 87 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -573,8 +573,8 @@ implementation if the function is called with unparametrized substitutions
573573
(i.e., substitutions where none of the substituted types are themselves
574574
parametrized).
575575
576-
However, with trait objects we have to make a table containing _every object
577-
that implements the trait_. Now, if it has type parameters, we need to add
576+
However, with trait objects we have to make a table containing _every_ object
577+
that implements the trait. Now, if it has type parameters, we need to add
578578
implementations for every type that implements the trait, and there could
579579
theoretically be an infinite number of types.
580580
@@ -609,9 +609,9 @@ fn call_foo(thing: Box<Trait>) {
609609
```
610610
611611
we don't just need to create a table of all implementations of all methods of
612-
`Trait`, we need to create a table of all implementations of `foo()`, _for each
613-
different type fed to `foo()`_. In this case this turns out to be (10 types
614-
implementing `Trait`)*(3 types being fed to `foo()`) = 30 implementations!
612+
`Trait`, we need to create such a table, for each different type fed to
613+
`foo()`. In this case this turns out to be (10 types implementing `Trait`)*(3
614+
types being fed to `foo()`) = 30 implementations!
615615
616616
With real world traits these numbers can grow drastically.
617617
@@ -684,19 +684,19 @@ If the trait `Foo` was deriving from something like `Super<String>` or
684684
`Super<T>` (where `Foo` itself is `Foo<T>`), this is okay, because given a type
685685
`get_a()` will definitely return an object of that type.
686686
687-
However, if it derives from `Super<Self>`, the method `get_a()` would return an
688-
object of unknown type when called on the function, _even though `Super` is
689-
object safe_. `Self` type parameters let us make object safe traits no longer
690-
safe, so they are forbidden when specifying supertraits.
687+
However, if it derives from `Super<Self>`, even though `Super` is object safe,
688+
the method `get_a()` would return an object of unknown type when called on the
689+
function. `Self` type parameters let us make object safe traits no longer safe,
690+
so they are forbidden when specifying supertraits.
691691
692692
There's no easy fix for this, generally code will need to be refactored so that
693693
you no longer need to derive from `Super<Self>`.
694694
"####,
695695

696696
E0079: r##"
697697
Enum variants which contain no data can be given a custom integer
698-
representation. This error indicates that the value provided is not an
699-
integer literal and is therefore invalid.
698+
representation. This error indicates that the value provided is not an integer
699+
literal and is therefore invalid.
700700
701701
For example, in the following code,
702702
@@ -708,18 +708,17 @@ enum Foo {
708708
709709
we try to set the representation to a string.
710710
711-
There's no general fix for this; if you can work with an integer
712-
then just set it to one:
711+
There's no general fix for this; if you can work with an integer then just set
712+
it to one:
713713
714714
```
715715
enum Foo {
716716
Q = 32
717717
}
718718
```
719719
720-
however if you actually wanted a mapping between variants
721-
and non-integer objects, it may be preferable to use a method with
722-
a match instead:
720+
however if you actually wanted a mapping between variants and non-integer
721+
objects, it may be preferable to use a method with a match instead:
723722
724723
```
725724
enum Foo { Q }
@@ -1156,6 +1155,73 @@ It is advisable to find out what the unhandled cases are and check for them,
11561155
returning an appropriate value or panicking if necessary.
11571156
"##,
11581157

1158+
E0270: r##"
1159+
Rust lets you define functions which are known to never return, i.e. are
1160+
"diverging", by marking its return type as `!`.
1161+
1162+
For example, the following functions never return:
1163+
1164+
```
1165+
fn foo() -> ! {
1166+
loop {}
1167+
}
1168+
1169+
fn bar() -> ! {
1170+
foo() // foo() is diverging, so this will diverge too
1171+
}
1172+
1173+
fn baz() -> ! {
1174+
panic!(); // this macro internally expands to a call to a diverging function
1175+
}
1176+
1177+
```
1178+
1179+
Such functions can be used in a place where a value is expected without
1180+
returning a value of that type, for instance:
1181+
1182+
```
1183+
let y = match x {
1184+
1 => 1,
1185+
2 => 4,
1186+
_ => foo() // diverging function called here
1187+
};
1188+
println!("{}", y)
1189+
```
1190+
1191+
If the third arm of the match block is reached, since `foo()` doesn't ever
1192+
return control to the match block, it is fine to use it in a place where an
1193+
integer was expected. The `match` block will never finish executing, and any
1194+
point where `y` (like the print statement) is needed will not be reached.
1195+
1196+
However, if we had a diverging function that actually does finish execution
1197+
1198+
```
1199+
fn foo() -> {
1200+
loop {break;}
1201+
}
1202+
```
1203+
1204+
then we would have an unknown value for `y` in the following code:
1205+
1206+
```
1207+
let y = match x {
1208+
1 => 1,
1209+
2 => 4,
1210+
_ => foo()
1211+
};
1212+
println!("{}", y);
1213+
```
1214+
1215+
In the previous example, the print statement was never reached when the wildcard
1216+
match arm was hit, so we were okay with `foo()` not returning an integer that we
1217+
could set to `y`. But in this example, `foo()` actually does return control, so
1218+
the print statement will be executed with an uninitialized value.
1219+
1220+
Obviously we cannot have functions which are allowed to be used in such
1221+
positions and yet can return control. So, if you are defining a function that
1222+
returns `!`, make sure that there is no way for it to actually finish executing.
1223+
"##,
1224+
11591225
E0271: r##"
11601226
This is because of a type mismatch between the associated type of some
11611227
trait (e.g. `T::Bar`, where `T` implements `trait Quux { type Bar; }`)
@@ -1292,6 +1358,11 @@ for v in &vs {
12921358
```
12931359
"##,
12941360

1361+
E0272: r##"
1362+
1363+
The `#[rustc_on_unimplemented]` attribute lets you specify
1364+
"##,
1365+
12951366
E0277: r##"
12961367
You tried to use a type which doesn't implement some trait in a place which
12971368
expected that trait. Erroneous code example:
@@ -1716,7 +1787,6 @@ register_diagnostics! {
17161787
// E0134,
17171788
// E0135,
17181789
E0264, // unknown external lang item
1719-
E0270, // computation may converge in a function marked as diverging
17201790
E0272, // rustc_on_unimplemented attribute refers to non-existent type parameter
17211791
E0273, // rustc_on_unimplemented must have named format arguments
17221792
E0274, // rustc_on_unimplemented must have a value

0 commit comments

Comments
 (0)