Skip to content

Commit 9b47586

Browse files
committed
update coercion docs
1 parent 0b5007e commit 9b47586

File tree

1 file changed

+18
-31
lines changed

1 file changed

+18
-31
lines changed

src/librustc_typeck/check/coercion.rs

+18-31
Original file line numberDiff line numberDiff line change
@@ -10,45 +10,30 @@
1010
//!
1111
//! Note that if we are expecting a reference, we will *reborrow*
1212
//! even if the argument provided was already a reference. This is
13-
//! useful for freezing mut/const things (that is, when the expected is &T
14-
//! but you have &const T or &mut T) and also for avoiding the linearity
13+
//! useful for freezing mut things (that is, when the expected type is &T
14+
//! but you have &mut T) and also for avoiding the linearity
1515
//! of mut things (when the expected is &mut T and you have &mut T). See
16-
//! the various `src/test/ui/coerce-reborrow-*.rs` tests for
16+
//! the various `src/test/ui/coerce/*.rs` tests for
1717
//! examples of where this is useful.
1818
//!
1919
//! ## Subtle note
2020
//!
21-
//! When deciding what type coercions to consider, we do not attempt to
22-
//! resolve any type variables we may encounter. This is because `b`
23-
//! represents the expected type "as the user wrote it", meaning that if
24-
//! the user defined a generic function like
21+
//! When infering the generic arguments of functions, the argument
22+
//! order is relevant, which can lead to the following edge case:
2523
//!
26-
//! fn foo<A>(a: A, b: A) { ... }
24+
//! ```rust
25+
//! fn foo<T>(a: T, b: T) {
26+
//! // ...
27+
//! }
2728
//!
28-
//! and then we wrote `foo(&1, @2)`, we will not auto-borrow
29-
//! either argument. In older code we went to some lengths to
30-
//! resolve the `b` variable, which could mean that we'd
31-
//! auto-borrow later arguments but not earlier ones, which
32-
//! seems very confusing.
29+
//! foo(&7i32, &mut 7i32);
30+
//! // This compiles, as we first infer `T` to be `&i32`,
31+
//! // and then coerce `&mut 7i32` to `&7i32`.
3332
//!
34-
//! ## Subtler note
35-
//!
36-
//! However, right now, if the user manually specifies the
37-
//! values for the type variables, as so:
38-
//!
39-
//! foo::<&int>(@1, @2)
40-
//!
41-
//! then we *will* auto-borrow, because we can't distinguish this from a
42-
//! function that declared `&int`. This is inconsistent but it's easiest
43-
//! at the moment. The right thing to do, I think, is to consider the
44-
//! *unsubstituted* type when deciding whether to auto-borrow, but the
45-
//! *substituted* type when considering the bounds and so forth. But most
46-
//! of our methods don't give access to the unsubstituted type, and
47-
//! rightly so because they'd be error-prone. So maybe the thing to do is
48-
//! to actually determine the kind of coercions that should occur
49-
//! separately and pass them in. Or maybe it's ok as is. Anyway, it's
50-
//! sort of a minor point so I've opted to leave it for later -- after all,
51-
//! we may want to adjust precisely when coercions occur.
33+
//! foo(&mut 7i32, &7i32);
34+
//! // This does not compile, as we first infer `T` to be `&mut i32`
35+
//! // and are then unable to coerce `&7i32` to `&mut i32`.
36+
//! ```
5237
5338
use crate::astconv::AstConv;
5439
use crate::check::{FnCtxt, Needs};
@@ -96,6 +81,8 @@ impl<'a, 'tcx> Deref for Coerce<'a, 'tcx> {
9681

9782
type CoerceResult<'tcx> = InferResult<'tcx, (Vec<Adjustment<'tcx>>, Ty<'tcx>)>;
9883

84+
/// Coercing a mutable reference to an immutable works, while
85+
/// coercing `&T` to `&mut T` should be forbidden.
9986
fn coerce_mutbls<'tcx>(
10087
from_mutbl: hir::Mutability,
10188
to_mutbl: hir::Mutability,

0 commit comments

Comments
 (0)