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

Don't use QueryNormalizer to normalize in rustdoc #102835

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
31 changes: 11 additions & 20 deletions src/librustdoc/clean/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use rustc_infer::infer::region_constraints::{Constraint, RegionConstraintData};
use rustc_middle::middle::resolve_lifetime as rl;
use rustc_middle::ty::fold::TypeFolder;
use rustc_middle::ty::InternalSubsts;
use rustc_middle::ty::{self, AdtKind, DefIdTree, EarlyBinder, Lift, Ty, TyCtxt};
use rustc_middle::ty::{self, AdtKind, DefIdTree, EarlyBinder, Lift, Ty, TyCtxt, TypeFoldable};
use rustc_middle::{bug, span_bug};
use rustc_span::hygiene::{AstPass, MacroKind};
use rustc_span::symbol::{kw, sym, Ident, Symbol};
Expand Down Expand Up @@ -983,6 +983,8 @@ fn clean_fn_decl_from_did_and_sig<'tcx>(
) -> FnDecl {
let mut names = did.map_or(&[] as &[_], |did| cx.tcx.fn_arg_names(did)).iter();

let sig = normalize(cx, sig).unwrap_or(sig);

// We assume all empty tuples are default return type. This theoretically can discard `-> ()`,
// but shouldn't change any code meaning.
let output = match clean_middle_ty(sig.skip_binder().output(), cx, None) {
Expand Down Expand Up @@ -1552,33 +1554,22 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T
}

/// Returns `None` if the type could not be normalized
fn normalize<'tcx>(cx: &mut DocContext<'tcx>, ty: Ty<'_>) -> Option<Ty<'tcx>> {
fn normalize<'tcx, T: TypeFoldable<'tcx>>(cx: &mut DocContext<'tcx>, value: T) -> Option<T> {
// HACK: low-churn fix for #79459 while we wait for a trait normalization fix
if !cx.tcx.sess.opts.unstable_opts.normalize_docs {
return None;
}

use crate::rustc_trait_selection::infer::TyCtxtInferExt;
use crate::rustc_trait_selection::traits::query::normalize::AtExt;
use rustc_middle::traits::ObligationCause;
if value.has_escaping_bound_vars() {
return None;
}

use rustc_trait_selection::infer::TyCtxtInferExt;
use rustc_trait_selection::traits;

// Try to normalize `<X as Y>::T` to a type
let lifted = ty.lift_to_tcx(cx.tcx).unwrap();
let infcx = cx.tcx.infer_ctxt().build();
let normalized = infcx
.at(&ObligationCause::dummy(), cx.param_env)
.normalize(lifted)
.map(|resolved| infcx.resolve_vars_if_possible(resolved.value));
match normalized {
Ok(normalized_value) => {
debug!("normalized {:?} to {:?}", ty, normalized_value);
Some(normalized_value)
}
Err(err) => {
debug!("failed to normalize {:?}: {:?}", ty, err);
None
}
}
traits::fully_normalize(&infcx, traits::ObligationCause::dummy(), cx.param_env, value).ok()
}

pub(crate) fn clean_middle_ty<'tcx>(
Expand Down
21 changes: 21 additions & 0 deletions src/test/rustdoc/issue-102835.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// compile-flags: -Znormalize-docs

#![feature(type_alias_impl_trait)]

trait Allocator {
type Buffer;
}

struct DefaultAllocator;

impl<T> Allocator for DefaultAllocator {
type Buffer = ();
}

type A = impl Fn(<DefaultAllocator as Allocator>::Buffer);

fn foo() -> A {
|_| ()
}

fn main() {}