Skip to content

Commit d5a9bc9

Browse files
committed
Auto merge of rust-lang#94392 - matthiaskrgr:rollup-npscf95, r=matthiaskrgr
Rollup of 5 pull requests Successful merges: - rust-lang#93400 (Do not suggest using a const parameter when there are bounds on an unused type parameter) - rust-lang#93982 (Provide extra note if synthetic type args are specified) - rust-lang#94087 (Remove unused `unsound_ignore_borrow_on_drop`) - rust-lang#94235 (chalk: Fix wrong debrujin index in opaque type handling.) - rust-lang#94306 (Avoid exhausting stack space in dominator compression) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 7c3331c + 648a8e3 commit d5a9bc9

File tree

17 files changed

+266
-115
lines changed

17 files changed

+266
-115
lines changed

compiler/rustc_data_structures/src/graph/dominators/mod.rs

+13-3
Original file line numberDiff line numberDiff line change
@@ -241,9 +241,19 @@ fn compress(
241241
v: PreorderIndex,
242242
) {
243243
assert!(is_processed(v, lastlinked));
244-
let u = ancestor[v];
245-
if is_processed(u, lastlinked) {
246-
compress(ancestor, lastlinked, semi, label, u);
244+
// Compute the processed list of ancestors
245+
//
246+
// We use a heap stack here to avoid recursing too deeply, exhausting the
247+
// stack space.
248+
let mut stack: smallvec::SmallVec<[_; 8]> = smallvec::smallvec![v];
249+
let mut u = ancestor[v];
250+
while is_processed(u, lastlinked) {
251+
stack.push(u);
252+
u = ancestor[u];
253+
}
254+
255+
// Then in reverse order, popping the stack
256+
for &[v, u] in stack.array_windows().rev() {
247257
if semi[label[u]] < semi[label[v]] {
248258
label[v] = label[u];
249259
}

compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs

+11-34
Original file line numberDiff line numberDiff line change
@@ -10,38 +10,11 @@ use rustc_middle::mir::*;
1010
/// At present, this is used as a very limited form of alias analysis. For example,
1111
/// `MaybeBorrowedLocals` is used to compute which locals are live during a yield expression for
1212
/// immovable generators.
13-
pub struct MaybeBorrowedLocals {
14-
ignore_borrow_on_drop: bool,
15-
}
16-
17-
impl MaybeBorrowedLocals {
18-
/// A dataflow analysis that records whether a pointer or reference exists that may alias the
19-
/// given local.
20-
pub fn all_borrows() -> Self {
21-
MaybeBorrowedLocals { ignore_borrow_on_drop: false }
22-
}
23-
}
13+
pub struct MaybeBorrowedLocals;
2414

2515
impl MaybeBorrowedLocals {
26-
/// During dataflow analysis, ignore the borrow that may occur when a place is dropped.
27-
///
28-
/// Drop terminators may call custom drop glue (`Drop::drop`), which takes `&mut self` as a
29-
/// parameter. In the general case, a drop impl could launder that reference into the
30-
/// surrounding environment through a raw pointer, thus creating a valid `*mut` pointing to the
31-
/// dropped local. We are not yet willing to declare this particular case UB, so we must treat
32-
/// all dropped locals as mutably borrowed for now. See discussion on [#61069].
33-
///
34-
/// In some contexts, we know that this borrow will never occur. For example, during
35-
/// const-eval, custom drop glue cannot be run. Code that calls this should document the
36-
/// assumptions that justify ignoring `Drop` terminators in this way.
37-
///
38-
/// [#61069]: https://github.com/rust-lang/rust/pull/61069
39-
pub fn unsound_ignore_borrow_on_drop(self) -> Self {
40-
MaybeBorrowedLocals { ignore_borrow_on_drop: true, ..self }
41-
}
42-
4316
fn transfer_function<'a, T>(&'a self, trans: &'a mut T) -> TransferFunction<'a, T> {
44-
TransferFunction { trans, ignore_borrow_on_drop: self.ignore_borrow_on_drop }
17+
TransferFunction { trans }
4518
}
4619
}
4720

@@ -92,7 +65,6 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeBorrowedLocals {
9265
/// A `Visitor` that defines the transfer function for `MaybeBorrowedLocals`.
9366
struct TransferFunction<'a, T> {
9467
trans: &'a mut T,
95-
ignore_borrow_on_drop: bool,
9668
}
9769

9870
impl<'tcx, T> Visitor<'tcx> for TransferFunction<'_, T>
@@ -146,10 +118,15 @@ where
146118
match terminator.kind {
147119
mir::TerminatorKind::Drop { place: dropped_place, .. }
148120
| mir::TerminatorKind::DropAndReplace { place: dropped_place, .. } => {
149-
// See documentation for `unsound_ignore_borrow_on_drop` for an explanation.
150-
if !self.ignore_borrow_on_drop {
151-
self.trans.gen(dropped_place.local);
152-
}
121+
// Drop terminators may call custom drop glue (`Drop::drop`), which takes `&mut
122+
// self` as a parameter. In the general case, a drop impl could launder that
123+
// reference into the surrounding environment through a raw pointer, thus creating
124+
// a valid `*mut` pointing to the dropped local. We are not yet willing to declare
125+
// this particular case UB, so we must treat all dropped locals as mutably borrowed
126+
// for now. See discussion on [#61069].
127+
//
128+
// [#61069]: https://github.com/rust-lang/rust/pull/61069
129+
self.trans.gen(dropped_place.local);
153130
}
154131

155132
TerminatorKind::Abort

compiler/rustc_mir_transform/src/generator.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -463,10 +463,8 @@ fn locals_live_across_suspend_points<'tcx>(
463463

464464
// Calculate the MIR locals which have been previously
465465
// borrowed (even if they are still active).
466-
let borrowed_locals_results = MaybeBorrowedLocals::all_borrows()
467-
.into_engine(tcx, body_ref)
468-
.pass_name("generator")
469-
.iterate_to_fixpoint();
466+
let borrowed_locals_results =
467+
MaybeBorrowedLocals.into_engine(tcx, body_ref).pass_name("generator").iterate_to_fixpoint();
470468

471469
let mut borrowed_locals_cursor =
472470
rustc_mir_dataflow::ResultsCursor::new(body_ref, &borrowed_locals_results);

compiler/rustc_traits/src/chalk/db.rs

+40-15
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
99
use rustc_middle::traits::ChalkRustInterner as RustInterner;
1010
use rustc_middle::ty::subst::{InternalSubsts, Subst, SubstsRef};
11-
use rustc_middle::ty::{self, AssocItemContainer, AssocKind, TyCtxt, TypeFoldable};
11+
use rustc_middle::ty::{self, AssocItemContainer, AssocKind, Ty, TyCtxt, TypeFoldable};
1212

1313
use rustc_ast::ast;
1414
use rustc_attr as attr;
@@ -482,21 +482,11 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
482482
.iter()
483483
.map(|(bound, _)| bound.subst(self.interner.tcx, &bound_vars))
484484
.map(|bound| {
485-
bound.fold_with(&mut ty::fold::BottomUpFolder {
485+
bound.fold_with(&mut ReplaceOpaqueTyFolder {
486486
tcx: self.interner.tcx,
487-
ty_op: |ty| {
488-
if let ty::Opaque(def_id, substs) = *ty.kind() {
489-
if def_id == opaque_ty_id.0 && substs == identity_substs {
490-
return self.interner.tcx.mk_ty(ty::Bound(
491-
ty::INNERMOST,
492-
ty::BoundTy::from(ty::BoundVar::from_u32(0)),
493-
));
494-
}
495-
}
496-
ty
497-
},
498-
lt_op: |lt| lt,
499-
ct_op: |ct| ct,
487+
opaque_ty_id,
488+
identity_substs,
489+
binder_index: ty::INNERMOST,
500490
})
501491
})
502492
.filter_map(|bound| {
@@ -739,3 +729,38 @@ fn binders_for<'tcx>(
739729
}),
740730
)
741731
}
732+
733+
struct ReplaceOpaqueTyFolder<'tcx> {
734+
tcx: TyCtxt<'tcx>,
735+
opaque_ty_id: chalk_ir::OpaqueTyId<RustInterner<'tcx>>,
736+
identity_substs: SubstsRef<'tcx>,
737+
binder_index: ty::DebruijnIndex,
738+
}
739+
740+
impl<'tcx> ty::TypeFolder<'tcx> for ReplaceOpaqueTyFolder<'tcx> {
741+
fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
742+
self.tcx
743+
}
744+
745+
fn fold_binder<T: TypeFoldable<'tcx>>(
746+
&mut self,
747+
t: ty::Binder<'tcx, T>,
748+
) -> ty::Binder<'tcx, T> {
749+
self.binder_index.shift_in(1);
750+
let t = t.super_fold_with(self);
751+
self.binder_index.shift_out(1);
752+
t
753+
}
754+
755+
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
756+
if let ty::Opaque(def_id, substs) = *ty.kind() {
757+
if def_id == self.opaque_ty_id.0 && substs == self.identity_substs {
758+
return self.tcx.mk_ty(ty::Bound(
759+
self.binder_index,
760+
ty::BoundTy::from(ty::BoundVar::from_u32(0)),
761+
));
762+
}
763+
}
764+
ty
765+
}
766+
}

compiler/rustc_traits/src/chalk/lowering.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,10 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Ty<RustInterner<'tcx>>> for Ty<'tcx> {
323323
ty::Closure(def_id, substs) => {
324324
chalk_ir::TyKind::Closure(chalk_ir::ClosureId(def_id), substs.lower_into(interner))
325325
}
326-
ty::Generator(_def_id, _substs, _) => unimplemented!(),
326+
ty::Generator(def_id, substs, _) => chalk_ir::TyKind::Generator(
327+
chalk_ir::GeneratorId(def_id),
328+
substs.lower_into(interner),
329+
),
327330
ty::GeneratorWitness(_) => unimplemented!(),
328331
ty::Never => chalk_ir::TyKind::Never,
329332
ty::Tuple(types) => {

compiler/rustc_typeck/src/astconv/generics.rs

+58-49
Original file line numberDiff line numberDiff line change
@@ -512,61 +512,69 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
512512
explicit_late_bound == ExplicitLateBound::Yes,
513513
);
514514

515-
let mut check_types_and_consts =
516-
|expected_min, expected_max, provided, params_offset, args_offset| {
517-
debug!(
518-
?expected_min,
519-
?expected_max,
520-
?provided,
521-
?params_offset,
522-
?args_offset,
523-
"check_types_and_consts"
515+
let mut check_types_and_consts = |expected_min,
516+
expected_max,
517+
expected_max_with_synth,
518+
provided,
519+
params_offset,
520+
args_offset| {
521+
debug!(
522+
?expected_min,
523+
?expected_max,
524+
?provided,
525+
?params_offset,
526+
?args_offset,
527+
"check_types_and_consts"
528+
);
529+
if (expected_min..=expected_max).contains(&provided) {
530+
return true;
531+
}
532+
533+
let num_default_params = expected_max - expected_min;
534+
535+
let gen_args_info = if provided > expected_max {
536+
invalid_args.extend(
537+
gen_args.args[args_offset + expected_max..args_offset + provided]
538+
.iter()
539+
.map(|arg| arg.span()),
524540
);
525-
if (expected_min..=expected_max).contains(&provided) {
526-
return true;
541+
let num_redundant_args = provided - expected_max;
542+
543+
// Provide extra note if synthetic arguments like `impl Trait` are specified.
544+
let synth_provided = provided <= expected_max_with_synth;
545+
546+
GenericArgsInfo::ExcessTypesOrConsts {
547+
num_redundant_args,
548+
num_default_params,
549+
args_offset,
550+
synth_provided,
527551
}
552+
} else {
553+
let num_missing_args = expected_max - provided;
528554

529-
let num_default_params = expected_max - expected_min;
555+
GenericArgsInfo::MissingTypesOrConsts {
556+
num_missing_args,
557+
num_default_params,
558+
args_offset,
559+
}
560+
};
530561

531-
let gen_args_info = if provided > expected_max {
532-
invalid_args.extend(
533-
gen_args.args[args_offset + expected_max..args_offset + provided]
534-
.iter()
535-
.map(|arg| arg.span()),
536-
);
537-
let num_redundant_args = provided - expected_max;
562+
debug!(?gen_args_info);
538563

539-
GenericArgsInfo::ExcessTypesOrConsts {
540-
num_redundant_args,
541-
num_default_params,
542-
args_offset,
543-
}
544-
} else {
545-
let num_missing_args = expected_max - provided;
564+
WrongNumberOfGenericArgs::new(
565+
tcx,
566+
gen_args_info,
567+
seg,
568+
gen_params,
569+
params_offset,
570+
gen_args,
571+
def_id,
572+
)
573+
.diagnostic()
574+
.emit_unless(gen_args.has_err());
546575

547-
GenericArgsInfo::MissingTypesOrConsts {
548-
num_missing_args,
549-
num_default_params,
550-
args_offset,
551-
}
552-
};
553-
554-
debug!(?gen_args_info);
555-
556-
WrongNumberOfGenericArgs::new(
557-
tcx,
558-
gen_args_info,
559-
seg,
560-
gen_params,
561-
params_offset,
562-
gen_args,
563-
def_id,
564-
)
565-
.diagnostic()
566-
.emit_unless(gen_args.has_err());
567-
568-
false
569-
};
576+
false
577+
};
570578

571579
let args_correct = {
572580
let expected_min = if infer_args {
@@ -582,6 +590,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
582590
check_types_and_consts(
583591
expected_min,
584592
param_counts.consts + named_type_param_count,
593+
param_counts.consts + named_type_param_count + synth_type_param_count,
585594
gen_args.num_generic_params(),
586595
param_counts.lifetimes + has_self as usize,
587596
gen_args.num_lifetime_params(),

compiler/rustc_typeck/src/check/wfcheck.rs

+32-4
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ use rustc_trait_selection::traits::{self, ObligationCause, ObligationCauseCode,
3131

3232
use std::convert::TryInto;
3333
use std::iter;
34+
use std::lazy::Lazy;
3435
use std::ops::ControlFlow;
3536

3637
/// Helper type of a temporary returned by `.for_item(...)`.
@@ -1720,8 +1721,29 @@ fn check_variances_for_type_defn<'tcx>(
17201721

17211722
identify_constrained_generic_params(tcx, ty_predicates, None, &mut constrained_parameters);
17221723

1724+
// Lazily calculated because it is only needed in case of an error.
1725+
let explicitly_bounded_params = Lazy::new(|| {
1726+
let icx = crate::collect::ItemCtxt::new(tcx, item.def_id.to_def_id());
1727+
hir_generics
1728+
.where_clause
1729+
.predicates
1730+
.iter()
1731+
.filter_map(|predicate| match predicate {
1732+
hir::WherePredicate::BoundPredicate(predicate) => {
1733+
match icx.to_ty(predicate.bounded_ty).kind() {
1734+
ty::Param(data) => Some(Parameter(data.index)),
1735+
_ => None,
1736+
}
1737+
}
1738+
_ => None,
1739+
})
1740+
.collect::<FxHashSet<_>>()
1741+
});
1742+
17231743
for (index, _) in variances.iter().enumerate() {
1724-
if constrained_parameters.contains(&Parameter(index as u32)) {
1744+
let parameter = Parameter(index as u32);
1745+
1746+
if constrained_parameters.contains(&parameter) {
17251747
continue;
17261748
}
17271749

@@ -1730,13 +1752,19 @@ fn check_variances_for_type_defn<'tcx>(
17301752
match param.name {
17311753
hir::ParamName::Error => {}
17321754
_ => {
1733-
report_bivariance(tcx, param);
1755+
let has_explicit_bounds =
1756+
!param.bounds.is_empty() || explicitly_bounded_params.contains(&parameter);
1757+
report_bivariance(tcx, param, has_explicit_bounds);
17341758
}
17351759
}
17361760
}
17371761
}
17381762

1739-
fn report_bivariance(tcx: TyCtxt<'_>, param: &rustc_hir::GenericParam<'_>) -> ErrorReported {
1763+
fn report_bivariance(
1764+
tcx: TyCtxt<'_>,
1765+
param: &rustc_hir::GenericParam<'_>,
1766+
has_explicit_bounds: bool,
1767+
) -> ErrorReported {
17401768
let span = param.span;
17411769
let param_name = param.name.ident().name;
17421770
let mut err = error_392(tcx, span, param_name);
@@ -1754,7 +1782,7 @@ fn report_bivariance(tcx: TyCtxt<'_>, param: &rustc_hir::GenericParam<'_>) -> Er
17541782
};
17551783
err.help(&msg);
17561784

1757-
if matches!(param.kind, rustc_hir::GenericParamKind::Type { .. }) {
1785+
if matches!(param.kind, hir::GenericParamKind::Type { .. }) && !has_explicit_bounds {
17581786
err.help(&format!(
17591787
"if you intended `{0}` to be a const parameter, use `const {0}: usize` instead",
17601788
param_name

compiler/rustc_typeck/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ This API is completely unstable and subject to change.
6868
#![feature(slice_partition_dedup)]
6969
#![feature(control_flow_enum)]
7070
#![feature(hash_drain_filter)]
71+
#![feature(once_cell)]
7172
#![recursion_limit = "256"]
7273
#![allow(rustc::potential_query_instability)]
7374

0 commit comments

Comments
 (0)