Skip to content

Commit 14dbfeb

Browse files
committed
Auto merge of rust-lang#99506 - Dylan-DPC:rollup-q3msucx, r=Dylan-DPC
Rollup of 7 pull requests Successful merges: - rust-lang#98101 (stdlib support for Apple WatchOS) - rust-lang#99345 (Do not allow typeck children items to constrain outer RPITs) - rust-lang#99383 (Formalize defining_use_anchor) - rust-lang#99436 (Add flag to configure `noalias` on `Box<T>`) - rust-lang#99483 (Fix a numerical underflow in tuple wrap suggestion) - rust-lang#99485 (Stop injecting `#[allow(unused_qualifications)]` in generated `derive` implementations) - rust-lang#99486 (Refactor: remove a string comparison between types in `check_str_addition`) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents d60d88f + 17a2832 commit 14dbfeb

Some content is hidden

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

57 files changed

+544
-332
lines changed

compiler/rustc_borrowck/src/consumers.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
use rustc_hir::def_id::LocalDefId;
44
use rustc_index::vec::IndexVec;
5-
use rustc_infer::infer::TyCtxtInferExt;
5+
use rustc_infer::infer::{DefiningAnchor, TyCtxtInferExt};
66
use rustc_middle::mir::Body;
77
use rustc_middle::ty::{self, TyCtxt};
88

@@ -31,7 +31,7 @@ pub fn get_body_with_borrowck_facts<'tcx>(
3131
def: ty::WithOptConstParam<LocalDefId>,
3232
) -> BodyWithBorrowckFacts<'tcx> {
3333
let (input_body, promoted) = tcx.mir_promoted(def);
34-
tcx.infer_ctxt().with_opaque_type_inference(def.did).enter(|infcx| {
34+
tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bind(def.did)).enter(|infcx| {
3535
let input_body: &Body<'_> = &input_body.borrow();
3636
let promoted: &IndexVec<_, _> = &promoted.borrow();
3737
*super::do_mir_borrowck(&infcx, input_body, promoted, true).1.unwrap()

compiler/rustc_borrowck/src/lib.rs

+9-6
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use rustc_hir as hir;
2424
use rustc_hir::def_id::LocalDefId;
2525
use rustc_index::bit_set::ChunkedBitSet;
2626
use rustc_index::vec::IndexVec;
27-
use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
27+
use rustc_infer::infer::{DefiningAnchor, InferCtxt, TyCtxtInferExt};
2828
use rustc_middle::mir::{
2929
traversal, Body, ClearCrossCrate, Local, Location, Mutability, Operand, Place, PlaceElem,
3030
PlaceRef, VarDebugInfoContents,
@@ -130,11 +130,14 @@ fn mir_borrowck<'tcx>(
130130
debug!("run query mir_borrowck: {}", tcx.def_path_str(def.did.to_def_id()));
131131
let hir_owner = tcx.hir().local_def_id_to_hir_id(def.did).owner;
132132

133-
let opt_closure_req = tcx.infer_ctxt().with_opaque_type_inference(hir_owner).enter(|infcx| {
134-
let input_body: &Body<'_> = &input_body.borrow();
135-
let promoted: &IndexVec<_, _> = &promoted.borrow();
136-
do_mir_borrowck(&infcx, input_body, promoted, false).0
137-
});
133+
let opt_closure_req = tcx
134+
.infer_ctxt()
135+
.with_opaque_type_inference(DefiningAnchor::Bind(hir_owner))
136+
.enter(|infcx| {
137+
let input_body: &Body<'_> = &input_body.borrow();
138+
let promoted: &IndexVec<_, _> = &promoted.borrow();
139+
do_mir_borrowck(&infcx, input_body, promoted, false).0
140+
});
138141
debug!("mir_borrowck done");
139142

140143
tcx.arena.alloc(opt_closure_req)

compiler/rustc_borrowck/src/region_infer/opaque_types.rs

+54-48
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ use rustc_data_structures::vec_map::VecMap;
33
use rustc_hir::def_id::LocalDefId;
44
use rustc_hir::OpaqueTyOrigin;
55
use rustc_infer::infer::error_reporting::unexpected_hidden_region_diagnostic;
6-
use rustc_infer::infer::InferCtxt;
76
use rustc_infer::infer::TyCtxtInferExt as _;
7+
use rustc_infer::infer::{DefiningAnchor, InferCtxt};
88
use rustc_infer::traits::{Obligation, ObligationCause, TraitEngine};
99
use rustc_middle::ty::fold::{TypeFolder, TypeSuperFoldable};
1010
use rustc_middle::ty::subst::{GenericArg, GenericArgKind, InternalSubsts};
@@ -269,59 +269,65 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
269269
// FIXME(oli-obk): Also do region checks here and then consider removing `check_opaque_meets_bounds` entirely.
270270
let param_env = self.tcx.param_env(def_id);
271271
let body_id = self.tcx.local_def_id_to_hir_id(def_id);
272-
self.tcx.infer_ctxt().enter(move |infcx| {
273-
// Require the hidden type to be well-formed with only the generics of the opaque type.
274-
// Defining use functions may have more bounds than the opaque type, which is ok, as long as the
275-
// hidden type is well formed even without those bounds.
276-
let predicate =
277-
ty::Binder::dummy(ty::PredicateKind::WellFormed(definition_ty.into()))
278-
.to_predicate(infcx.tcx);
279-
let mut fulfillment_cx = <dyn TraitEngine<'tcx>>::new(infcx.tcx);
280-
281-
// Require that the hidden type actually fulfills all the bounds of the opaque type, even without
282-
// the bounds that the function supplies.
283-
match infcx.register_hidden_type(
284-
OpaqueTypeKey { def_id, substs: id_substs },
285-
ObligationCause::misc(instantiated_ty.span, body_id),
286-
param_env,
287-
definition_ty,
288-
origin,
289-
) {
290-
Ok(infer_ok) => {
291-
for obligation in infer_ok.obligations {
292-
fulfillment_cx.register_predicate_obligation(&infcx, obligation);
272+
// HACK This bubble is required for this tests to pass:
273+
// type-alias-impl-trait/issue-67844-nested-opaque.rs
274+
self.tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bubble).enter(
275+
move |infcx| {
276+
// Require the hidden type to be well-formed with only the generics of the opaque type.
277+
// Defining use functions may have more bounds than the opaque type, which is ok, as long as the
278+
// hidden type is well formed even without those bounds.
279+
let predicate =
280+
ty::Binder::dummy(ty::PredicateKind::WellFormed(definition_ty.into()))
281+
.to_predicate(infcx.tcx);
282+
let mut fulfillment_cx = <dyn TraitEngine<'tcx>>::new(infcx.tcx);
283+
284+
// Require that the hidden type actually fulfills all the bounds of the opaque type, even without
285+
// the bounds that the function supplies.
286+
match infcx.register_hidden_type(
287+
OpaqueTypeKey { def_id, substs: id_substs },
288+
ObligationCause::misc(instantiated_ty.span, body_id),
289+
param_env,
290+
definition_ty,
291+
origin,
292+
) {
293+
Ok(infer_ok) => {
294+
for obligation in infer_ok.obligations {
295+
fulfillment_cx.register_predicate_obligation(&infcx, obligation);
296+
}
297+
}
298+
Err(err) => {
299+
infcx
300+
.report_mismatched_types(
301+
&ObligationCause::misc(instantiated_ty.span, body_id),
302+
self.tcx.mk_opaque(def_id.to_def_id(), id_substs),
303+
definition_ty,
304+
err,
305+
)
306+
.emit();
293307
}
294308
}
295-
Err(err) => {
296-
infcx
297-
.report_mismatched_types(
298-
&ObligationCause::misc(instantiated_ty.span, body_id),
299-
self.tcx.mk_opaque(def_id.to_def_id(), id_substs),
300-
definition_ty,
301-
err,
302-
)
303-
.emit();
304-
}
305-
}
306309

307-
fulfillment_cx.register_predicate_obligation(
308-
&infcx,
309-
Obligation::misc(instantiated_ty.span, body_id, param_env, predicate),
310-
);
310+
fulfillment_cx.register_predicate_obligation(
311+
&infcx,
312+
Obligation::misc(instantiated_ty.span, body_id, param_env, predicate),
313+
);
311314

312-
// Check that all obligations are satisfied by the implementation's
313-
// version.
314-
let errors = fulfillment_cx.select_all_or_error(&infcx);
315+
// Check that all obligations are satisfied by the implementation's
316+
// version.
317+
let errors = fulfillment_cx.select_all_or_error(&infcx);
315318

316-
let _ = infcx.inner.borrow_mut().opaque_type_storage.take_opaque_types();
319+
// This is still required for many(half of the tests in ui/type-alias-impl-trait)
320+
// tests to pass
321+
let _ = infcx.inner.borrow_mut().opaque_type_storage.take_opaque_types();
317322

318-
if errors.is_empty() {
319-
definition_ty
320-
} else {
321-
infcx.report_fulfillment_errors(&errors, None, false);
322-
self.tcx.ty_error()
323-
}
324-
})
323+
if errors.is_empty() {
324+
definition_ty
325+
} else {
326+
infcx.report_fulfillment_errors(&errors, None, false);
327+
self.tcx.ty_error()
328+
}
329+
},
330+
)
325331
} else {
326332
definition_ty
327333
}

compiler/rustc_borrowck/src/type_check/mod.rs

+21
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKi
2121
use rustc_infer::infer::{
2222
InferCtxt, InferOk, LateBoundRegion, LateBoundRegionConversionTime, NllRegionVariableOrigin,
2323
};
24+
use rustc_infer::traits::ObligationCause;
2425
use rustc_middle::mir::tcx::PlaceTy;
2526
use rustc_middle::mir::visit::{NonMutatingUseContext, PlaceContext, Visitor};
2627
use rustc_middle::mir::AssertKind;
@@ -224,6 +225,26 @@ pub(crate) fn type_check<'mir, 'tcx>(
224225
)
225226
.unwrap();
226227
let mut hidden_type = infcx.resolve_vars_if_possible(decl.hidden_type);
228+
// Check that RPITs are only constrained in their outermost
229+
// function, otherwise report a mismatched types error.
230+
if let OpaqueTyOrigin::FnReturn(parent) | OpaqueTyOrigin::AsyncFn(parent)
231+
= infcx.opaque_ty_origin_unchecked(opaque_type_key.def_id, hidden_type.span)
232+
&& parent.to_def_id() != body.source.def_id()
233+
{
234+
infcx
235+
.report_mismatched_types(
236+
&ObligationCause::misc(
237+
hidden_type.span,
238+
infcx.tcx.hir().local_def_id_to_hir_id(
239+
body.source.def_id().expect_local(),
240+
),
241+
),
242+
infcx.tcx.mk_opaque(opaque_type_key.def_id.to_def_id(), opaque_type_key.substs),
243+
hidden_type.ty,
244+
ty::error::TypeError::Mismatch,
245+
)
246+
.emit();
247+
}
227248
trace!(
228249
"finalized opaque type {:?} to {:#?}",
229250
opaque_type_key,

compiler/rustc_builtin_macros/src/deriving/generic/mod.rs

+1-9
Original file line numberDiff line numberDiff line change
@@ -727,16 +727,8 @@ impl<'a> TraitDef<'a> {
727727

728728
let attr = cx.attribute(cx.meta_word(self.span, sym::automatically_derived));
729729
let opt_trait_ref = Some(trait_ref);
730-
let unused_qual = {
731-
let word = rustc_ast::attr::mk_nested_word_item(Ident::new(
732-
sym::unused_qualifications,
733-
self.span,
734-
));
735-
let list = rustc_ast::attr::mk_list_item(Ident::new(sym::allow, self.span), vec![word]);
736-
cx.attribute(list)
737-
};
738730

739-
let mut a = vec![attr, unused_qual];
731+
let mut a = vec![attr];
740732
a.extend(self.attributes.iter().cloned());
741733

742734
cx.item(

compiler/rustc_infer/src/infer/mod.rs

+25-7
Original file line numberDiff line numberDiff line change
@@ -239,17 +239,31 @@ impl<'tcx> InferCtxtInner<'tcx> {
239239
}
240240
}
241241

242+
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
243+
pub enum DefiningAnchor {
244+
/// `DefId` of the item.
245+
Bind(LocalDefId),
246+
/// When opaque types are not resolved, we `Bubble` up, meaning
247+
/// return the opaque/hidden type pair from query, for caller of query to handle it.
248+
Bubble,
249+
/// Used to catch type mismatch errors when handling opaque types.
250+
Error,
251+
}
252+
242253
pub struct InferCtxt<'a, 'tcx> {
243254
pub tcx: TyCtxt<'tcx>,
244255

245256
/// The `DefId` of the item in whose context we are performing inference or typeck.
246257
/// It is used to check whether an opaque type use is a defining use.
247258
///
248-
/// If it is `None`, we can't resolve opaque types here and need to bubble up
259+
/// If it is `DefiningAnchor::Bubble`, we can't resolve opaque types here and need to bubble up
249260
/// the obligation. This frequently happens for
250261
/// short lived InferCtxt within queries. The opaque type obligations are forwarded
251262
/// to the outside until the end up in an `InferCtxt` for typeck or borrowck.
252-
pub defining_use_anchor: Option<LocalDefId>,
263+
///
264+
/// It is default value is `DefiningAnchor::Error`, this way it is easier to catch errors that
265+
/// might come up during inference or typeck.
266+
pub defining_use_anchor: DefiningAnchor,
253267

254268
/// During type-checking/inference of a body, `in_progress_typeck_results`
255269
/// contains a reference to the typeck results being built up, which are
@@ -526,7 +540,7 @@ impl<'tcx> fmt::Display for FixupError<'tcx> {
526540
pub struct InferCtxtBuilder<'tcx> {
527541
tcx: TyCtxt<'tcx>,
528542
fresh_typeck_results: Option<RefCell<ty::TypeckResults<'tcx>>>,
529-
defining_use_anchor: Option<LocalDefId>,
543+
defining_use_anchor: DefiningAnchor,
530544
}
531545

532546
pub trait TyCtxtInferExt<'tcx> {
@@ -535,7 +549,11 @@ pub trait TyCtxtInferExt<'tcx> {
535549

536550
impl<'tcx> TyCtxtInferExt<'tcx> for TyCtxt<'tcx> {
537551
fn infer_ctxt(self) -> InferCtxtBuilder<'tcx> {
538-
InferCtxtBuilder { tcx: self, defining_use_anchor: None, fresh_typeck_results: None }
552+
InferCtxtBuilder {
553+
tcx: self,
554+
defining_use_anchor: DefiningAnchor::Error,
555+
fresh_typeck_results: None,
556+
}
539557
}
540558
}
541559

@@ -545,7 +563,7 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
545563
/// Will also change the scope for opaque type defining use checks to the given owner.
546564
pub fn with_fresh_in_progress_typeck_results(mut self, table_owner: LocalDefId) -> Self {
547565
self.fresh_typeck_results = Some(RefCell::new(ty::TypeckResults::new(table_owner)));
548-
self.with_opaque_type_inference(table_owner)
566+
self.with_opaque_type_inference(DefiningAnchor::Bind(table_owner))
549567
}
550568

551569
/// Whenever the `InferCtxt` should be able to handle defining uses of opaque types,
@@ -554,8 +572,8 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
554572
/// It is only meant to be called in two places, for typeck
555573
/// (via `with_fresh_in_progress_typeck_results`) and for the inference context used
556574
/// in mir borrowck.
557-
pub fn with_opaque_type_inference(mut self, defining_use_anchor: LocalDefId) -> Self {
558-
self.defining_use_anchor = Some(defining_use_anchor);
575+
pub fn with_opaque_type_inference(mut self, defining_use_anchor: DefiningAnchor) -> Self {
576+
self.defining_use_anchor = defining_use_anchor;
559577
self
560578
}
561579

0 commit comments

Comments
 (0)