Skip to content

Commit 8ba11b7

Browse files
committed
review
1 parent 0ac5a0b commit 8ba11b7

File tree

3 files changed

+36
-5
lines changed

3 files changed

+36
-5
lines changed

compiler/rustc_middle/src/query/mod.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -1375,8 +1375,9 @@ rustc_queries! {
13751375
/// type-checking etc, and it does not normalize specializable
13761376
/// associated types.
13771377
///
1378-
/// You should pretty much only use this if an `infcx` is available,
1379-
/// otherwise use a `TypingEnv`.
1378+
/// You should almost certainly not use this. If you already have an InferCtxt, then
1379+
/// you should also probably have a `ParamEnv` from when it was built. If you don't,
1380+
/// then you should take a `TypingEnv` to ensure that you handle opaque types correctly.
13801381
query param_env(def_id: DefId) -> ty::ParamEnv<'tcx> {
13811382
desc { |tcx| "computing normalized predicates of `{}`", tcx.def_path_str(def_id) }
13821383
feedable

compiler/rustc_mir_transform/src/post_analysis_normalize.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
//! Normalizes MIR in TypingMode::PostAnalysis mode, most notably revealing
2-
//! its opaques.
1+
//! Normalizes MIR in `TypingMode::PostAnalysis`` mode, most notably revealing
2+
//! its opaques. We also only normalize specializable associated items once in
3+
//! `PostAnalysis` mode.
34
45
use rustc_middle::mir::visit::*;
56
use rustc_middle::mir::*;

compiler/rustc_type_ir/src/infer_ctxt.rs

+30-1
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,38 @@ pub enum TypingMode<I: Interner> {
3939
///
4040
/// We only normalize opaque types which may get defined by the current body,
4141
/// which are stored in `defining_opaque_types`.
42+
///
43+
/// We also refuse to project any associated type that is marked `default`.
44+
/// Non-`default` ("final") types are always projected. This is necessary in
45+
/// general for soundness of specialization. However, we *could* allow projections
46+
/// in fully-monomorphic cases. We choose not to, because we prefer for `default type`
47+
/// to force the type definition to be treated abstractly by any consumers of the
48+
/// impl. Concretely, that means that the following example will
49+
/// fail to compile:
50+
///
51+
/// ```compile_fail,E0308
52+
/// #![feature(specialization)]
53+
/// trait Assoc {
54+
/// type Output;
55+
/// }
56+
///
57+
/// impl<T> Assoc for T {
58+
/// default type Output = bool;
59+
/// }
60+
///
61+
/// fn main() {
62+
/// let x: <() as Assoc>::Output = true;
63+
/// }
64+
/// ```
4265
Analysis { defining_opaque_types: I::DefiningOpaqueTypes },
4366
/// After analysis, mostly during codegen and MIR optimizations, we're able to
44-
/// reveal all opaque types.
67+
/// reveal all opaque types. As the concrete type should *never* be observable
68+
/// directly by the user, this should not be used by checks which may expose
69+
/// such details to the user.
70+
///
71+
/// There are some exceptions to this as for example `layout_of` and const-evaluation
72+
/// always run in `PostAnalysis` mode, even when used during analysis. This exposes
73+
/// some information about the underlying type to users, but not the type itself.
4574
PostAnalysis,
4675
}
4776

0 commit comments

Comments
 (0)