Skip to content

Commit 5d3c6d6

Browse files
committed
Auto merge of rust-lang#98691 - matthiaskrgr:rollup-ymsa64p, r=matthiaskrgr
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
2 parents bf45371 + 943c6c7 commit 5d3c6d6

File tree

67 files changed

+475
-264
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

67 files changed

+475
-264
lines changed

compiler/rustc_infer/src/infer/opaque_types.rs

+7-14
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use hir::{HirId, OpaqueTyOrigin};
55
use rustc_data_structures::sync::Lrc;
66
use rustc_data_structures::vec_map::VecMap;
77
use rustc_hir as hir;
8-
use rustc_middle::traits::{ObligationCause, ObligationCauseCode};
8+
use rustc_middle::traits::ObligationCause;
99
use rustc_middle::ty::fold::BottomUpFolder;
1010
use rustc_middle::ty::subst::{GenericArgKind, Subst};
1111
use rustc_middle::ty::{
@@ -44,30 +44,23 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
4444
ty: Ty<'tcx>,
4545
body_id: HirId,
4646
span: Span,
47-
code: ObligationCauseCode<'tcx>,
4847
param_env: ty::ParamEnv<'tcx>,
4948
) -> InferOk<'tcx, Ty<'tcx>> {
5049
if !ty.has_opaque_types() {
5150
return InferOk { value: ty, obligations: vec![] };
5251
}
5352
let mut obligations = vec![];
53+
let replace_opaque_type = |def_id| self.opaque_type_origin(def_id, span).is_some();
5454
let value = ty.fold_with(&mut ty::fold::BottomUpFolder {
5555
tcx: self.tcx,
5656
lt_op: |lt| lt,
5757
ct_op: |ct| ct,
5858
ty_op: |ty| match *ty.kind() {
59-
// Closures can't create hidden types for opaque types of their parent, as they
60-
// do not have all the outlives information available. Also `type_of` looks for
61-
// hidden types in the owner (so the closure's parent), so it would not find these
62-
// definitions.
63-
ty::Opaque(def_id, _substs)
64-
if matches!(
65-
self.opaque_type_origin(def_id, span),
66-
Some(OpaqueTyOrigin::FnReturn(..))
67-
) =>
68-
{
69-
let span = if span.is_dummy() { self.tcx.def_span(def_id) } else { span };
70-
let cause = ObligationCause::new(span, body_id, code.clone());
59+
ty::Opaque(def_id, _substs) if replace_opaque_type(def_id) => {
60+
let def_span = self.tcx.def_span(def_id);
61+
let span = if span.contains(def_span) { def_span } else { span };
62+
let code = traits::ObligationCauseCode::OpaqueReturnType(None);
63+
let cause = ObligationCause::new(span, body_id, code);
7164
// FIXME(compiler-errors): We probably should add a new TypeVariableOriginKind
7265
// for opaque types, and then use that kind to fix the spans for type errors
7366
// that we see later on.

compiler/rustc_typeck/src/check/check.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,7 @@ pub(super) fn check_fn<'a, 'tcx>(
9595
fcx.register_infer_ok_obligations(fcx.infcx.replace_opaque_types_with_inference_vars(
9696
declared_ret_ty,
9797
body.value.hir_id,
98-
DUMMY_SP,
99-
traits::ObligationCauseCode::OpaqueReturnType(None),
98+
decl.output.span(),
10099
param_env,
101100
));
102101
// If we replaced declared_ret_ty with infer vars, then we must be infering

compiler/rustc_typeck/src/check/closure.rs

+59-59
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,10 @@ use rustc_hir::lang_items::LangItem;
1010
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
1111
use rustc_infer::infer::LateBoundRegionConversionTime;
1212
use rustc_infer::infer::{InferOk, InferResult};
13-
use rustc_infer::traits::ObligationCauseCode;
1413
use rustc_middle::ty::fold::TypeFoldable;
1514
use rustc_middle::ty::subst::InternalSubsts;
1615
use rustc_middle::ty::{self, Ty};
1716
use rustc_span::source_map::Span;
18-
use rustc_span::DUMMY_SP;
1917
use rustc_target::spec::abi::Abi;
2018
use rustc_trait_selection::traits::error_reporting::ArgKind;
2119
use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _;
@@ -429,14 +427,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
429427
// in this binder we are creating.
430428
assert!(!expected_sig.sig.skip_binder().has_vars_bound_above(ty::INNERMOST));
431429
let bound_sig = expected_sig.sig.map_bound(|sig| {
432-
let output = self.hide_parent_opaque_types(
433-
sig.output(),
434-
expected_sig.cause_span.unwrap_or(DUMMY_SP),
435-
body.id().hir_id,
436-
);
437430
self.tcx.mk_fn_sig(
438431
sig.inputs().iter().cloned(),
439-
output,
432+
sig.output(),
440433
sig.c_variadic,
441434
hir::Unsafety::Normal,
442435
Abi::RustCall,
@@ -608,23 +601,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
608601
// function.
609602
Some(hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Fn)) => {
610603
debug!("closure is async fn body");
611-
self.deduce_future_output_from_obligations(expr_def_id).unwrap_or_else(|| {
612-
// AFAIK, deducing the future output
613-
// always succeeds *except* in error cases
614-
// like #65159. I'd like to return Error
615-
// here, but I can't because I can't
616-
// easily (and locally) prove that we
617-
// *have* reported an
618-
// error. --nikomatsakis
619-
astconv.ty_infer(None, decl.output.span())
620-
})
604+
self.deduce_future_output_from_obligations(expr_def_id, body.id().hir_id)
605+
.unwrap_or_else(|| {
606+
// AFAIK, deducing the future output
607+
// always succeeds *except* in error cases
608+
// like #65159. I'd like to return Error
609+
// here, but I can't because I can't
610+
// easily (and locally) prove that we
611+
// *have* reported an
612+
// error. --nikomatsakis
613+
astconv.ty_infer(None, decl.output.span())
614+
})
621615
}
622616

623617
_ => astconv.ty_infer(None, decl.output.span()),
624618
},
625619
};
626-
let supplied_return =
627-
self.hide_parent_opaque_types(supplied_return, decl.output.span(), body.id().hir_id);
628620

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

648-
fn hide_parent_opaque_types(&self, ty: Ty<'tcx>, span: Span, body_id: hir::HirId) -> Ty<'tcx> {
649-
let InferOk { value, obligations } = self.replace_opaque_types_with_inference_vars(
650-
ty,
651-
body_id,
652-
span,
653-
ObligationCauseCode::MiscObligation,
654-
self.param_env,
655-
);
656-
self.register_predicates(obligations);
657-
value
658-
}
659-
660640
/// Invoked when we are translating the generator that results
661641
/// from desugaring an `async fn`. Returns the "sugared" return
662642
/// type of the `async fn` -- that is, the return type that the
663643
/// user specified. The "desugared" return type is an `impl
664644
/// Future<Output = T>`, so we do this by searching through the
665645
/// obligations to extract the `T`.
666646
#[instrument(skip(self), level = "debug")]
667-
fn deduce_future_output_from_obligations(&self, expr_def_id: DefId) -> Option<Ty<'tcx>> {
647+
fn deduce_future_output_from_obligations(
648+
&self,
649+
expr_def_id: DefId,
650+
body_id: hir::HirId,
651+
) -> Option<Ty<'tcx>> {
668652
let ret_coercion = self.ret_coercion.as_ref().unwrap_or_else(|| {
669653
span_bug!(self.tcx.def_span(expr_def_id), "async fn generator outside of a fn")
670654
});
671655

672656
let ret_ty = ret_coercion.borrow().expected_ty();
673657
let ret_ty = self.inh.infcx.shallow_resolve(ret_ty);
674-
let (def_id, substs) = match *ret_ty.kind() {
675-
ty::Opaque(def_id, substs) => (def_id, substs),
658+
659+
let get_future_output = |predicate: ty::Predicate<'tcx>, span| {
660+
// Search for a pending obligation like
661+
//
662+
// `<R as Future>::Output = T`
663+
//
664+
// where R is the return type we are expecting. This type `T`
665+
// will be our output.
666+
let bound_predicate = predicate.kind();
667+
if let ty::PredicateKind::Projection(proj_predicate) = bound_predicate.skip_binder() {
668+
self.deduce_future_output_from_projection(
669+
span,
670+
bound_predicate.rebind(proj_predicate),
671+
)
672+
} else {
673+
None
674+
}
675+
};
676+
677+
let output_ty = match *ret_ty.kind() {
678+
ty::Infer(ty::TyVar(ret_vid)) => {
679+
self.obligations_for_self_ty(ret_vid).find_map(|(_, obligation)| {
680+
get_future_output(obligation.predicate, obligation.cause.span)
681+
})?
682+
}
683+
ty::Opaque(def_id, substs) => self
684+
.tcx
685+
.bound_explicit_item_bounds(def_id)
686+
.transpose_iter()
687+
.map(|e| e.map_bound(|e| *e).transpose_tuple2())
688+
.find_map(|(p, s)| get_future_output(p.subst(self.tcx, substs), s.0))?,
676689
ty::Error(_) => return None,
677690
_ => span_bug!(
678691
self.tcx.def_span(expr_def_id),
679692
"async fn generator return type not an inference variable"
680693
),
681694
};
682695

683-
let item_bounds = self.tcx.bound_explicit_item_bounds(def_id);
684-
685-
// Search for a pending obligation like
686-
//
687-
// `<R as Future>::Output = T`
688-
//
689-
// where R is the return type we are expecting. This type `T`
690-
// will be our output.
691-
let output_ty = item_bounds
692-
.transpose_iter()
693-
.map(|e| e.map_bound(|e| *e).transpose_tuple2())
694-
.find_map(|(predicate, span)| {
695-
let bound_predicate = predicate.subst(self.tcx, substs).kind();
696-
if let ty::PredicateKind::Projection(proj_predicate) = bound_predicate.skip_binder()
697-
{
698-
self.deduce_future_output_from_projection(
699-
span.0,
700-
bound_predicate.rebind(proj_predicate),
701-
)
702-
} else {
703-
None
704-
}
705-
});
696+
// async fn that have opaque types in their return type need to redo the conversion to inference variables
697+
// as they fetch the still opaque version from the signature.
698+
let InferOk { value: output_ty, obligations } = self
699+
.replace_opaque_types_with_inference_vars(
700+
output_ty,
701+
body_id,
702+
self.tcx.def_span(expr_def_id),
703+
self.param_env,
704+
);
705+
self.register_predicates(obligations);
706706

707707
debug!("deduce_future_output_from_obligations: output_ty={:?}", output_ty);
708-
output_ty
708+
Some(output_ty)
709709
}
710710

711711
/// Given a projection like

src/librustdoc/config.rs

+15-8
Original file line numberDiff line numberDiff line change
@@ -218,12 +218,9 @@ pub(crate) struct RenderOptions {
218218
///
219219
/// Be aware: This option can come both from the CLI and from crate attributes!
220220
pub(crate) playground_url: Option<String>,
221-
/// Whether to sort modules alphabetically on a module page instead of using declaration order.
222-
/// `true` by default.
223-
//
224-
// FIXME(misdreavus): the flag name is `--sort-modules-by-appearance` but the meaning is
225-
// inverted once read.
226-
pub(crate) sort_modules_alphabetically: bool,
221+
/// What sorting mode to use for module pages.
222+
/// `ModuleSorting::Alphabetical` by default.
223+
pub(crate) module_sorting: ModuleSorting,
227224
/// List of themes to extend the docs with. Original argument name is included to assist in
228225
/// displaying errors if it fails a theme check.
229226
pub(crate) themes: Vec<StylePath>,
@@ -281,6 +278,12 @@ pub(crate) struct RenderOptions {
281278
pub(crate) no_emit_shared: bool,
282279
}
283280

281+
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
282+
pub(crate) enum ModuleSorting {
283+
DeclarationOrder,
284+
Alphabetical,
285+
}
286+
284287
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
285288
pub(crate) enum EmitType {
286289
Unversioned,
@@ -650,7 +653,11 @@ impl Options {
650653
let proc_macro_crate = crate_types.contains(&CrateType::ProcMacro);
651654
let playground_url = matches.opt_str("playground-url");
652655
let maybe_sysroot = matches.opt_str("sysroot").map(PathBuf::from);
653-
let sort_modules_alphabetically = !matches.opt_present("sort-modules-by-appearance");
656+
let module_sorting = if matches.opt_present("sort-modules-by-appearance") {
657+
ModuleSorting::DeclarationOrder
658+
} else {
659+
ModuleSorting::Alphabetical
660+
};
654661
let resource_suffix = matches.opt_str("resource-suffix").unwrap_or_default();
655662
let enable_minification = !matches.opt_present("disable-minification");
656663
let markdown_no_toc = matches.opt_present("markdown-no-toc");
@@ -731,7 +738,7 @@ impl Options {
731738
external_html,
732739
id_map,
733740
playground_url,
734-
sort_modules_alphabetically,
741+
module_sorting,
735742
themes,
736743
extension_css,
737744
extern_html_root_urls,

src/librustdoc/html/render/context.rs

+10-7
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use super::{
2222
};
2323

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

283-
if self.shared.sort_modules_alphabetically {
284-
for items in map.values_mut() {
285-
items.sort();
283+
match self.shared.module_sorting {
284+
ModuleSorting::Alphabetical => {
285+
for items in map.values_mut() {
286+
items.sort();
287+
}
286288
}
289+
ModuleSorting::DeclarationOrder => {}
287290
}
288291
map
289292
}
@@ -394,7 +397,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
394397
external_html,
395398
id_map,
396399
playground_url,
397-
sort_modules_alphabetically,
400+
module_sorting,
398401
themes: style_files,
399402
default_settings,
400403
extension_css,
@@ -476,7 +479,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
476479
issue_tracker_base_url,
477480
layout,
478481
created_dirs: Default::default(),
479-
sort_modules_alphabetically,
482+
module_sorting,
480483
style_files,
481484
resource_suffix,
482485
static_root_path,

src/librustdoc/html/render/print_item.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use super::{
2323
AssocItemLink, Context, ImplRenderingParameters,
2424
};
2525
use crate::clean;
26+
use crate::config::ModuleSorting;
2627
use crate::formats::item_type::ItemType;
2728
use crate::formats::{AssocItemRender, Impl, RenderMode};
2829
use crate::html::escape::Escape;
@@ -246,8 +247,11 @@ fn item_module(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Item, items:
246247
compare_names(lhs.as_str(), rhs.as_str())
247248
}
248249

249-
if cx.shared.sort_modules_alphabetically {
250-
indices.sort_by(|&i1, &i2| cmp(&items[i1], &items[i2], i1, i2, cx.tcx()));
250+
match cx.shared.module_sorting {
251+
ModuleSorting::Alphabetical => {
252+
indices.sort_by(|&i1, &i2| cmp(&items[i1], &items[i2], i1, i2, cx.tcx()));
253+
}
254+
ModuleSorting::DeclarationOrder => {}
251255
}
252256
// This call is to remove re-export duplicates in cases such as:
253257
//

src/librustdoc/json/conversions.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ fn from_clean_item(item: clean::Item, tcx: TyCtxt<'_>) -> ItemEnum {
255255
AssocTypeItem(t, b) => ItemEnum::AssocType {
256256
generics: t.generics.into_tcx(tcx),
257257
bounds: b.into_iter().map(|x| x.into_tcx(tcx)).collect(),
258-
default: t.item_type.map(|ty| ty.into_tcx(tcx)),
258+
default: Some(t.item_type.unwrap_or(t.type_).into_tcx(tcx)),
259259
},
260260
// `convert_item` early returns `None` for striped items and keywords.
261261
StrippedItem(_) | KeywordItem(_) => unreachable!(),
+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// Regression test for <https://github.com/rust-lang/rust/issues/98658>
2+
3+
#![no_std]
4+
5+
// @has blanket_impls.json
6+
// @has - "$.index[*][?(@.name=='Error')].kind" \"assoc_type\"
7+
// @has - "$.index[*][?(@.name=='Error')].inner.default.kind" \"resolved_path\"
8+
// @has - "$.index[*][?(@.name=='Error')].inner.default.inner.name" \"Infallible\"
9+
pub struct ForBlanketTryFromImpl;

src/test/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ impl Thing for AssocNoCopy {
3030
type Out = Box<dyn Bar<Assoc: Copy>>;
3131

3232
fn func() -> Self::Out {
33-
Box::new(AssocNoCopy)
3433
//~^ ERROR the trait bound `String: Copy` is not satisfied
34+
Box::new(AssocNoCopy)
3535
}
3636
}

0 commit comments

Comments
 (0)