Skip to content

Commit

Permalink
Auto merge of rust-lang#98691 - matthiaskrgr:rollup-ymsa64p, r=matthi…
Browse files Browse the repository at this point in the history
…askrgr

Rollup of 6 pull requests

Successful merges:

 - rust-lang#96727 (Make TAIT behave exactly like RPIT)
 - rust-lang#98681 (rustdoc-json: Make default value of blanket impl assoc types work)
 - rust-lang#98682 (add tests for ICE 94432)
 - rust-lang#98683 (add test for ice 68875)
 - rust-lang#98685 (Replace `sort_modules_alphabetically` boolean with enum)
 - rust-lang#98687 (add test for 47814)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Jun 30, 2022
2 parents bf45371 + 943c6c7 commit 5d3c6d6
Show file tree
Hide file tree
Showing 67 changed files with 475 additions and 264 deletions.
21 changes: 7 additions & 14 deletions compiler/rustc_infer/src/infer/opaque_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use hir::{HirId, OpaqueTyOrigin};
use rustc_data_structures::sync::Lrc;
use rustc_data_structures::vec_map::VecMap;
use rustc_hir as hir;
use rustc_middle::traits::{ObligationCause, ObligationCauseCode};
use rustc_middle::traits::ObligationCause;
use rustc_middle::ty::fold::BottomUpFolder;
use rustc_middle::ty::subst::{GenericArgKind, Subst};
use rustc_middle::ty::{
Expand Down Expand Up @@ -44,30 +44,23 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
ty: Ty<'tcx>,
body_id: HirId,
span: Span,
code: ObligationCauseCode<'tcx>,
param_env: ty::ParamEnv<'tcx>,
) -> InferOk<'tcx, Ty<'tcx>> {
if !ty.has_opaque_types() {
return InferOk { value: ty, obligations: vec![] };
}
let mut obligations = vec![];
let replace_opaque_type = |def_id| self.opaque_type_origin(def_id, span).is_some();
let value = ty.fold_with(&mut ty::fold::BottomUpFolder {
tcx: self.tcx,
lt_op: |lt| lt,
ct_op: |ct| ct,
ty_op: |ty| match *ty.kind() {
// Closures can't create hidden types for opaque types of their parent, as they
// do not have all the outlives information available. Also `type_of` looks for
// hidden types in the owner (so the closure's parent), so it would not find these
// definitions.
ty::Opaque(def_id, _substs)
if matches!(
self.opaque_type_origin(def_id, span),
Some(OpaqueTyOrigin::FnReturn(..))
) =>
{
let span = if span.is_dummy() { self.tcx.def_span(def_id) } else { span };
let cause = ObligationCause::new(span, body_id, code.clone());
ty::Opaque(def_id, _substs) if replace_opaque_type(def_id) => {
let def_span = self.tcx.def_span(def_id);
let span = if span.contains(def_span) { def_span } else { span };
let code = traits::ObligationCauseCode::OpaqueReturnType(None);
let cause = ObligationCause::new(span, body_id, code);
// FIXME(compiler-errors): We probably should add a new TypeVariableOriginKind
// for opaque types, and then use that kind to fix the spans for type errors
// that we see later on.
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_typeck/src/check/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,7 @@ pub(super) fn check_fn<'a, 'tcx>(
fcx.register_infer_ok_obligations(fcx.infcx.replace_opaque_types_with_inference_vars(
declared_ret_ty,
body.value.hir_id,
DUMMY_SP,
traits::ObligationCauseCode::OpaqueReturnType(None),
decl.output.span(),
param_env,
));
// If we replaced declared_ret_ty with infer vars, then we must be infering
Expand Down
118 changes: 59 additions & 59 deletions compiler/rustc_typeck/src/check/closure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,10 @@ use rustc_hir::lang_items::LangItem;
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc_infer::infer::LateBoundRegionConversionTime;
use rustc_infer::infer::{InferOk, InferResult};
use rustc_infer::traits::ObligationCauseCode;
use rustc_middle::ty::fold::TypeFoldable;
use rustc_middle::ty::subst::InternalSubsts;
use rustc_middle::ty::{self, Ty};
use rustc_span::source_map::Span;
use rustc_span::DUMMY_SP;
use rustc_target::spec::abi::Abi;
use rustc_trait_selection::traits::error_reporting::ArgKind;
use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _;
Expand Down Expand Up @@ -429,14 +427,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// in this binder we are creating.
assert!(!expected_sig.sig.skip_binder().has_vars_bound_above(ty::INNERMOST));
let bound_sig = expected_sig.sig.map_bound(|sig| {
let output = self.hide_parent_opaque_types(
sig.output(),
expected_sig.cause_span.unwrap_or(DUMMY_SP),
body.id().hir_id,
);
self.tcx.mk_fn_sig(
sig.inputs().iter().cloned(),
output,
sig.output(),
sig.c_variadic,
hir::Unsafety::Normal,
Abi::RustCall,
Expand Down Expand Up @@ -608,23 +601,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// function.
Some(hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Fn)) => {
debug!("closure is async fn body");
self.deduce_future_output_from_obligations(expr_def_id).unwrap_or_else(|| {
// AFAIK, deducing the future output
// always succeeds *except* in error cases
// like #65159. I'd like to return Error
// here, but I can't because I can't
// easily (and locally) prove that we
// *have* reported an
// error. --nikomatsakis
astconv.ty_infer(None, decl.output.span())
})
self.deduce_future_output_from_obligations(expr_def_id, body.id().hir_id)
.unwrap_or_else(|| {
// AFAIK, deducing the future output
// always succeeds *except* in error cases
// like #65159. I'd like to return Error
// here, but I can't because I can't
// easily (and locally) prove that we
// *have* reported an
// error. --nikomatsakis
astconv.ty_infer(None, decl.output.span())
})
}

_ => astconv.ty_infer(None, decl.output.span()),
},
};
let supplied_return =
self.hide_parent_opaque_types(supplied_return, decl.output.span(), body.id().hir_id);

let result = ty::Binder::bind_with_vars(
self.tcx.mk_fn_sig(
Expand All @@ -645,67 +637,75 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
result
}

fn hide_parent_opaque_types(&self, ty: Ty<'tcx>, span: Span, body_id: hir::HirId) -> Ty<'tcx> {
let InferOk { value, obligations } = self.replace_opaque_types_with_inference_vars(
ty,
body_id,
span,
ObligationCauseCode::MiscObligation,
self.param_env,
);
self.register_predicates(obligations);
value
}

/// Invoked when we are translating the generator that results
/// from desugaring an `async fn`. Returns the "sugared" return
/// type of the `async fn` -- that is, the return type that the
/// user specified. The "desugared" return type is an `impl
/// Future<Output = T>`, so we do this by searching through the
/// obligations to extract the `T`.
#[instrument(skip(self), level = "debug")]
fn deduce_future_output_from_obligations(&self, expr_def_id: DefId) -> Option<Ty<'tcx>> {
fn deduce_future_output_from_obligations(
&self,
expr_def_id: DefId,
body_id: hir::HirId,
) -> Option<Ty<'tcx>> {
let ret_coercion = self.ret_coercion.as_ref().unwrap_or_else(|| {
span_bug!(self.tcx.def_span(expr_def_id), "async fn generator outside of a fn")
});

let ret_ty = ret_coercion.borrow().expected_ty();
let ret_ty = self.inh.infcx.shallow_resolve(ret_ty);
let (def_id, substs) = match *ret_ty.kind() {
ty::Opaque(def_id, substs) => (def_id, substs),

let get_future_output = |predicate: ty::Predicate<'tcx>, span| {
// Search for a pending obligation like
//
// `<R as Future>::Output = T`
//
// where R is the return type we are expecting. This type `T`
// will be our output.
let bound_predicate = predicate.kind();
if let ty::PredicateKind::Projection(proj_predicate) = bound_predicate.skip_binder() {
self.deduce_future_output_from_projection(
span,
bound_predicate.rebind(proj_predicate),
)
} else {
None
}
};

let output_ty = match *ret_ty.kind() {
ty::Infer(ty::TyVar(ret_vid)) => {
self.obligations_for_self_ty(ret_vid).find_map(|(_, obligation)| {
get_future_output(obligation.predicate, obligation.cause.span)
})?
}
ty::Opaque(def_id, substs) => self
.tcx
.bound_explicit_item_bounds(def_id)
.transpose_iter()
.map(|e| e.map_bound(|e| *e).transpose_tuple2())
.find_map(|(p, s)| get_future_output(p.subst(self.tcx, substs), s.0))?,
ty::Error(_) => return None,
_ => span_bug!(
self.tcx.def_span(expr_def_id),
"async fn generator return type not an inference variable"
),
};

let item_bounds = self.tcx.bound_explicit_item_bounds(def_id);

// Search for a pending obligation like
//
// `<R as Future>::Output = T`
//
// where R is the return type we are expecting. This type `T`
// will be our output.
let output_ty = item_bounds
.transpose_iter()
.map(|e| e.map_bound(|e| *e).transpose_tuple2())
.find_map(|(predicate, span)| {
let bound_predicate = predicate.subst(self.tcx, substs).kind();
if let ty::PredicateKind::Projection(proj_predicate) = bound_predicate.skip_binder()
{
self.deduce_future_output_from_projection(
span.0,
bound_predicate.rebind(proj_predicate),
)
} else {
None
}
});
// async fn that have opaque types in their return type need to redo the conversion to inference variables
// as they fetch the still opaque version from the signature.
let InferOk { value: output_ty, obligations } = self
.replace_opaque_types_with_inference_vars(
output_ty,
body_id,
self.tcx.def_span(expr_def_id),
self.param_env,
);
self.register_predicates(obligations);

debug!("deduce_future_output_from_obligations: output_ty={:?}", output_ty);
output_ty
Some(output_ty)
}

/// Given a projection like
Expand Down
23 changes: 15 additions & 8 deletions src/librustdoc/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -218,12 +218,9 @@ pub(crate) struct RenderOptions {
///
/// Be aware: This option can come both from the CLI and from crate attributes!
pub(crate) playground_url: Option<String>,
/// Whether to sort modules alphabetically on a module page instead of using declaration order.
/// `true` by default.
//
// FIXME(misdreavus): the flag name is `--sort-modules-by-appearance` but the meaning is
// inverted once read.
pub(crate) sort_modules_alphabetically: bool,
/// What sorting mode to use for module pages.
/// `ModuleSorting::Alphabetical` by default.
pub(crate) module_sorting: ModuleSorting,
/// List of themes to extend the docs with. Original argument name is included to assist in
/// displaying errors if it fails a theme check.
pub(crate) themes: Vec<StylePath>,
Expand Down Expand Up @@ -281,6 +278,12 @@ pub(crate) struct RenderOptions {
pub(crate) no_emit_shared: bool,
}

#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub(crate) enum ModuleSorting {
DeclarationOrder,
Alphabetical,
}

#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub(crate) enum EmitType {
Unversioned,
Expand Down Expand Up @@ -650,7 +653,11 @@ impl Options {
let proc_macro_crate = crate_types.contains(&CrateType::ProcMacro);
let playground_url = matches.opt_str("playground-url");
let maybe_sysroot = matches.opt_str("sysroot").map(PathBuf::from);
let sort_modules_alphabetically = !matches.opt_present("sort-modules-by-appearance");
let module_sorting = if matches.opt_present("sort-modules-by-appearance") {
ModuleSorting::DeclarationOrder
} else {
ModuleSorting::Alphabetical
};
let resource_suffix = matches.opt_str("resource-suffix").unwrap_or_default();
let enable_minification = !matches.opt_present("disable-minification");
let markdown_no_toc = matches.opt_present("markdown-no-toc");
Expand Down Expand Up @@ -731,7 +738,7 @@ impl Options {
external_html,
id_map,
playground_url,
sort_modules_alphabetically,
module_sorting,
themes,
extension_css,
extern_html_root_urls,
Expand Down
17 changes: 10 additions & 7 deletions src/librustdoc/html/render/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use super::{
};

use crate::clean::{self, types::ExternalLocation, ExternalCrate};
use crate::config::RenderOptions;
use crate::config::{ModuleSorting, RenderOptions};
use crate::docfs::{DocFS, PathError};
use crate::error::Error;
use crate::formats::cache::Cache;
Expand Down Expand Up @@ -95,7 +95,7 @@ pub(crate) struct SharedContext<'tcx> {
created_dirs: RefCell<FxHashSet<PathBuf>>,
/// This flag indicates whether listings of modules (in the side bar and documentation itself)
/// should be ordered alphabetically or in order of appearance (in the source code).
pub(super) sort_modules_alphabetically: bool,
pub(super) module_sorting: ModuleSorting,
/// Additional CSS files to be added to the generated docs.
pub(crate) style_files: Vec<StylePath>,
/// Suffix to be added on resource files (if suffix is "-v2" then "light.css" becomes
Expand Down Expand Up @@ -280,10 +280,13 @@ impl<'tcx> Context<'tcx> {
}
}

if self.shared.sort_modules_alphabetically {
for items in map.values_mut() {
items.sort();
match self.shared.module_sorting {
ModuleSorting::Alphabetical => {
for items in map.values_mut() {
items.sort();
}
}
ModuleSorting::DeclarationOrder => {}
}
map
}
Expand Down Expand Up @@ -394,7 +397,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
external_html,
id_map,
playground_url,
sort_modules_alphabetically,
module_sorting,
themes: style_files,
default_settings,
extension_css,
Expand Down Expand Up @@ -476,7 +479,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
issue_tracker_base_url,
layout,
created_dirs: Default::default(),
sort_modules_alphabetically,
module_sorting,
style_files,
resource_suffix,
static_root_path,
Expand Down
8 changes: 6 additions & 2 deletions src/librustdoc/html/render/print_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ use super::{
AssocItemLink, Context, ImplRenderingParameters,
};
use crate::clean;
use crate::config::ModuleSorting;
use crate::formats::item_type::ItemType;
use crate::formats::{AssocItemRender, Impl, RenderMode};
use crate::html::escape::Escape;
Expand Down Expand Up @@ -246,8 +247,11 @@ fn item_module(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Item, items:
compare_names(lhs.as_str(), rhs.as_str())
}

if cx.shared.sort_modules_alphabetically {
indices.sort_by(|&i1, &i2| cmp(&items[i1], &items[i2], i1, i2, cx.tcx()));
match cx.shared.module_sorting {
ModuleSorting::Alphabetical => {
indices.sort_by(|&i1, &i2| cmp(&items[i1], &items[i2], i1, i2, cx.tcx()));
}
ModuleSorting::DeclarationOrder => {}
}
// This call is to remove re-export duplicates in cases such as:
//
Expand Down
2 changes: 1 addition & 1 deletion src/librustdoc/json/conversions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ fn from_clean_item(item: clean::Item, tcx: TyCtxt<'_>) -> ItemEnum {
AssocTypeItem(t, b) => ItemEnum::AssocType {
generics: t.generics.into_tcx(tcx),
bounds: b.into_iter().map(|x| x.into_tcx(tcx)).collect(),
default: t.item_type.map(|ty| ty.into_tcx(tcx)),
default: Some(t.item_type.unwrap_or(t.type_).into_tcx(tcx)),
},
// `convert_item` early returns `None` for striped items and keywords.
StrippedItem(_) | KeywordItem(_) => unreachable!(),
Expand Down
9 changes: 9 additions & 0 deletions src/test/rustdoc-json/blanket_impls.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Regression test for <https://github.com/rust-lang/rust/issues/98658>

#![no_std]

// @has blanket_impls.json
// @has - "$.index[*][?(@.name=='Error')].kind" \"assoc_type\"
// @has - "$.index[*][?(@.name=='Error')].inner.default.kind" \"resolved_path\"
// @has - "$.index[*][?(@.name=='Error')].inner.default.inner.name" \"Infallible\"
pub struct ForBlanketTryFromImpl;
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ impl Thing for AssocNoCopy {
type Out = Box<dyn Bar<Assoc: Copy>>;

fn func() -> Self::Out {
Box::new(AssocNoCopy)
//~^ ERROR the trait bound `String: Copy` is not satisfied
Box::new(AssocNoCopy)
}
}
Loading

0 comments on commit 5d3c6d6

Please sign in to comment.