Skip to content

Commit cec7d94

Browse files
committed
Add example and extra documentation
1 parent 542383f commit cec7d94

File tree

1 file changed

+32
-0
lines changed
  • src/librustc_typeck/check

1 file changed

+32
-0
lines changed

src/librustc_typeck/check/mod.rs

+32
Original file line numberDiff line numberDiff line change
@@ -879,6 +879,30 @@ fn used_trait_imports(tcx: TyCtxt<'_>, def_id: DefId) -> &DefIdSet {
879879
/// variables introduced by the projection of associated types. This ensures that
880880
/// any opaque types used in the signature continue to refer to generic parameters,
881881
/// allowing them to be considered for defining uses in the function body
882+
///
883+
/// For example, consider this code.
884+
///
885+
/// ```rust
886+
/// trait MyTrait {
887+
/// type MyItem;
888+
/// fn use_it(self) -> Self::MyItem
889+
/// }
890+
/// impl<T, I> MyTrait for T where T: Iterator<Item = I> {
891+
/// type MyItem = impl Iterator<Item = I>;
892+
/// fn use_it(self) -> Self::MyItem {
893+
/// self
894+
/// }
895+
/// }
896+
/// ```
897+
///
898+
/// When we normalize the signature of `use_it` from the impl block,
899+
/// we will normalize `Self::MyItem` to the opaque type `impl Iterator<Item = I>`
900+
/// However, this projection result may contain inference variables, due
901+
/// to the way that projection works. We didn't have any inference variables
902+
/// in the signature to begin with - leaving them in will cause us to incorrectly
903+
/// conclude that we don't have a defining use of `MyItem`. By mapping inference
904+
/// variables back to the actual generic parameters, we will correctly see that
905+
/// we have a defining use of `MyItem`
882906
fn fixup_opaque_types<'tcx, T>(tcx: TyCtxt<'tcx>, val: &T) -> T where T: TypeFoldable<'tcx> {
883907
struct FixupFolder<'tcx> {
884908
tcx: TyCtxt<'tcx>
@@ -893,6 +917,14 @@ fn fixup_opaque_types<'tcx, T>(tcx: TyCtxt<'tcx>, val: &T) -> T where T: TypeFol
893917
match ty.kind {
894918
ty::Opaque(def_id, substs) => {
895919
debug!("fixup_opaque_types: found type {:?}", ty);
920+
// Here, we replace any inference variables that occur within
921+
// the substs of an opaque type. By definition, any type occuring
922+
// in the substs has a corresponding generic parameter, which is what
923+
// we replace it with.
924+
// This replacement is only run on the function signature, so any
925+
// inference variables that we come across must be the rust of projection
926+
// (there's no other way for a user to get inference variables into
927+
// a function signature).
896928
if ty.needs_infer() {
897929
let new_substs = InternalSubsts::for_item(self.tcx, def_id, |param, _| {
898930
let old_param = substs[param.index as usize];

0 commit comments

Comments
 (0)