Skip to content

Rollup of 8 pull requests #121054

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

Closed
wants to merge 16 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
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
24 changes: 20 additions & 4 deletions compiler/rustc_borrowck/src/type_check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1432,7 +1432,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
return;
}
};
let (sig, map) = tcx.instantiate_bound_regions(sig, |br| {
let (unnormalized_sig, map) = tcx.instantiate_bound_regions(sig, |br| {
use crate::renumber::RegionCtxt;

let region_ctxt_fn = || {
Expand All @@ -1454,7 +1454,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
region_ctxt_fn,
)
});
debug!(?sig);
debug!(?unnormalized_sig);
// IMPORTANT: We have to prove well formed for the function signature before
// we normalize it, as otherwise types like `<&'a &'b () as Trait>::Assoc`
// get normalized away, causing us to ignore the `'b: 'a` bound used by the function.
Expand All @@ -1464,15 +1464,31 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
//
// See #91068 for an example.
self.prove_predicates(
sig.inputs_and_output.iter().map(|ty| {
unnormalized_sig.inputs_and_output.iter().map(|ty| {
ty::Binder::dummy(ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(
ty.into(),
)))
}),
term_location.to_locations(),
ConstraintCategory::Boring,
);
let sig = self.normalize(sig, term_location);

let sig = self.normalize(unnormalized_sig, term_location);
// HACK(#114936): `WF(sig)` does not imply `WF(normalized(sig))`
// with built-in `Fn` implementations, since the impl may not be
// well-formed itself.
if sig != unnormalized_sig {
self.prove_predicates(
sig.inputs_and_output.iter().map(|ty| {
ty::Binder::dummy(ty::PredicateKind::Clause(
ty::ClauseKind::WellFormed(ty.into()),
))
}),
term_location.to_locations(),
ConstraintCategory::Boring,
);
}

self.check_call_dest(body, term, &sig, *destination, *target, term_location);

// The ordinary liveness rules will ensure that all
Expand Down
48 changes: 20 additions & 28 deletions compiler/rustc_infer/src/infer/at.rs
Original file line number Diff line number Diff line change
Expand Up @@ -285,13 +285,11 @@ impl<'a, 'tcx> Trace<'a, 'tcx> {
T: Relate<'tcx>,
{
let Trace { at, trace, a_is_expected } = self;
at.infcx.commit_if_ok(|_| {
let mut fields = at.infcx.combine_fields(trace, at.param_env, define_opaque_types);
fields
.sub(a_is_expected)
.relate(a, b)
.map(move |_| InferOk { value: (), obligations: fields.obligations })
})
let mut fields = at.infcx.combine_fields(trace, at.param_env, define_opaque_types);
fields
.sub(a_is_expected)
.relate(a, b)
.map(move |_| InferOk { value: (), obligations: fields.obligations })
}

/// Makes `a == b`; the expectation is set by the call to
Expand All @@ -302,13 +300,11 @@ impl<'a, 'tcx> Trace<'a, 'tcx> {
T: Relate<'tcx>,
{
let Trace { at, trace, a_is_expected } = self;
at.infcx.commit_if_ok(|_| {
let mut fields = at.infcx.combine_fields(trace, at.param_env, define_opaque_types);
fields
.equate(a_is_expected)
.relate(a, b)
.map(move |_| InferOk { value: (), obligations: fields.obligations })
})
let mut fields = at.infcx.combine_fields(trace, at.param_env, define_opaque_types);
fields
.equate(a_is_expected)
.relate(a, b)
.map(move |_| InferOk { value: (), obligations: fields.obligations })
}

#[instrument(skip(self), level = "debug")]
Expand All @@ -317,13 +313,11 @@ impl<'a, 'tcx> Trace<'a, 'tcx> {
T: Relate<'tcx>,
{
let Trace { at, trace, a_is_expected } = self;
at.infcx.commit_if_ok(|_| {
let mut fields = at.infcx.combine_fields(trace, at.param_env, define_opaque_types);
fields
.lub(a_is_expected)
.relate(a, b)
.map(move |t| InferOk { value: t, obligations: fields.obligations })
})
let mut fields = at.infcx.combine_fields(trace, at.param_env, define_opaque_types);
fields
.lub(a_is_expected)
.relate(a, b)
.map(move |t| InferOk { value: t, obligations: fields.obligations })
}

#[instrument(skip(self), level = "debug")]
Expand All @@ -332,13 +326,11 @@ impl<'a, 'tcx> Trace<'a, 'tcx> {
T: Relate<'tcx>,
{
let Trace { at, trace, a_is_expected } = self;
at.infcx.commit_if_ok(|_| {
let mut fields = at.infcx.combine_fields(trace, at.param_env, define_opaque_types);
fields
.glb(a_is_expected)
.relate(a, b)
.map(move |t| InferOk { value: t, obligations: fields.obligations })
})
let mut fields = at.infcx.combine_fields(trace, at.param_env, define_opaque_types);
fields
.glb(a_is_expected)
.relate(a, b)
.map(move |t| InferOk { value: t, obligations: fields.obligations })
}
}

Expand Down
66 changes: 32 additions & 34 deletions compiler/rustc_infer/src/infer/canonical/query_response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -620,42 +620,40 @@ impl<'tcx> InferCtxt<'tcx> {
variables1: &OriginalQueryValues<'tcx>,
variables2: impl Fn(BoundVar) -> GenericArg<'tcx>,
) -> InferResult<'tcx, ()> {
self.commit_if_ok(|_| {
let mut obligations = vec![];
for (index, value1) in variables1.var_values.iter().enumerate() {
let value2 = variables2(BoundVar::new(index));

match (value1.unpack(), value2.unpack()) {
(GenericArgKind::Type(v1), GenericArgKind::Type(v2)) => {
obligations.extend(
self.at(cause, param_env)
.eq(DefineOpaqueTypes::Yes, v1, v2)?
.into_obligations(),
);
}
(GenericArgKind::Lifetime(re1), GenericArgKind::Lifetime(re2))
if re1.is_erased() && re2.is_erased() =>
{
// no action needed
}
(GenericArgKind::Lifetime(v1), GenericArgKind::Lifetime(v2)) => {
obligations.extend(
self.at(cause, param_env)
.eq(DefineOpaqueTypes::Yes, v1, v2)?
.into_obligations(),
);
}
(GenericArgKind::Const(v1), GenericArgKind::Const(v2)) => {
let ok = self.at(cause, param_env).eq(DefineOpaqueTypes::Yes, v1, v2)?;
obligations.extend(ok.into_obligations());
}
_ => {
bug!("kind mismatch, cannot unify {:?} and {:?}", value1, value2,);
}
let mut obligations = vec![];
for (index, value1) in variables1.var_values.iter().enumerate() {
let value2 = variables2(BoundVar::new(index));

match (value1.unpack(), value2.unpack()) {
(GenericArgKind::Type(v1), GenericArgKind::Type(v2)) => {
obligations.extend(
self.at(cause, param_env)
.eq(DefineOpaqueTypes::Yes, v1, v2)?
.into_obligations(),
);
}
(GenericArgKind::Lifetime(re1), GenericArgKind::Lifetime(re2))
if re1.is_erased() && re2.is_erased() =>
{
// no action needed
}
(GenericArgKind::Lifetime(v1), GenericArgKind::Lifetime(v2)) => {
obligations.extend(
self.at(cause, param_env)
.eq(DefineOpaqueTypes::Yes, v1, v2)?
.into_obligations(),
);
}
(GenericArgKind::Const(v1), GenericArgKind::Const(v2)) => {
let ok = self.at(cause, param_env).eq(DefineOpaqueTypes::Yes, v1, v2)?;
obligations.extend(ok.into_obligations());
}
_ => {
bug!("kind mismatch, cannot unify {:?} and {:?}", value1, value2,);
}
}
Ok(InferOk { value: (), obligations })
})
}
Ok(InferOk { value: (), obligations })
}
}

Expand Down
14 changes: 14 additions & 0 deletions compiler/rustc_trait_selection/src/solve/assembly/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,13 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
let mut consider_impls_for_simplified_type = |simp| {
if let Some(impls_for_type) = trait_impls.non_blanket_impls().get(&simp) {
for &impl_def_id in impls_for_type {
// For every `default impl`, there's always a non-default `impl`
// that will *also* apply. There's no reason to register a candidate
// for this impl, since it is *not* proof that the trait goal holds.
if tcx.defaultness(impl_def_id).is_default() {
return;
}

match G::consider_impl_candidate(self, goal, impl_def_id) {
Ok(candidate) => candidates.push(candidate),
Err(NoSolution) => (),
Expand Down Expand Up @@ -440,6 +447,13 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
let tcx = self.tcx();
let trait_impls = tcx.trait_impls_of(goal.predicate.trait_def_id(tcx));
for &impl_def_id in trait_impls.blanket_impls() {
// For every `default impl`, there's always a non-default `impl`
// that will *also* apply. There's no reason to register a candidate
// for this impl, since it is *not* proof that the trait goal holds.
if tcx.defaultness(impl_def_id).is_default() {
return;
}

match G::consider_impl_candidate(self, goal, impl_def_id) {
Ok(candidate) => candidates.push(candidate),
Err(NoSolution) => (),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
{
return;
}

// For every `default impl`, there's always a non-default `impl`
// that will *also* apply. There's no reason to register a candidate
// for this impl, since it is *not* proof that the trait goal holds.
if self.tcx().defaultness(impl_def_id).is_default() {
return;
}

if self.reject_fn_ptr_impls(
impl_def_id,
obligation,
Expand Down
12 changes: 6 additions & 6 deletions compiler/rustc_trait_selection/src/traits/select/confirmation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,13 +192,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
&mut obligations,
);

obligations.extend(self.infcx.commit_if_ok(|_| {
obligations.extend(
self.infcx
.at(&obligation.cause, obligation.param_env)
.sup(DefineOpaqueTypes::No, placeholder_trait_predicate, candidate)
.map(|InferOk { obligations, .. }| obligations)
.map_err(|_| Unimplemented)
})?);
.map_err(|_| Unimplemented)?,
);

// FIXME(compiler-errors): I don't think this is needed.
if let ty::Alias(ty::Projection, alias_ty) = placeholder_self_ty.kind() {
Expand Down Expand Up @@ -532,13 +532,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
&mut nested,
);

nested.extend(self.infcx.commit_if_ok(|_| {
nested.extend(
self.infcx
.at(&obligation.cause, obligation.param_env)
.sup(DefineOpaqueTypes::No, obligation_trait_ref, upcast_trait_ref)
.map(|InferOk { obligations, .. }| obligations)
.map_err(|_| Unimplemented)
})?);
.map_err(|_| Unimplemented)?,
);

// Check supertraits hold. This is so that their associated type bounds
// will be checked in the code below.
Expand Down
6 changes: 3 additions & 3 deletions library/std/src/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ pub struct Child {
/// The handle for writing to the child's standard input (stdin), if it
/// has been captured. You might find it helpful to do
///
/// ```compile_fail,E0425
/// ```ignore (incomplete)
/// let stdin = child.stdin.take().unwrap();
/// ```
///
Expand All @@ -183,7 +183,7 @@ pub struct Child {
/// The handle for reading from the child's standard output (stdout), if it
/// has been captured. You might find it helpful to do
///
/// ```compile_fail,E0425
/// ```ignore (incomplete)
/// let stdout = child.stdout.take().unwrap();
/// ```
///
Expand All @@ -195,7 +195,7 @@ pub struct Child {
/// The handle for reading from the child's standard error (stderr), if it
/// has been captured. You might find it helpful to do
///
/// ```compile_fail,E0425
/// ```ignore (incomplete)
/// let stderr = child.stderr.take().unwrap();
/// ```
///
Expand Down
52 changes: 13 additions & 39 deletions src/librustdoc/clean/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -254,16 +254,14 @@ fn clean_poly_trait_ref_with_bindings<'tcx>(
}

fn clean_lifetime<'tcx>(lifetime: &hir::Lifetime, cx: &mut DocContext<'tcx>) -> Lifetime {
let def = cx.tcx.named_bound_var(lifetime.hir_id);
if let Some(
rbv::ResolvedArg::EarlyBound(node_id)
| rbv::ResolvedArg::LateBound(_, _, node_id)
| rbv::ResolvedArg::Free(_, node_id),
) = def
rbv::ResolvedArg::EarlyBound(did)
| rbv::ResolvedArg::LateBound(_, _, did)
| rbv::ResolvedArg::Free(_, did),
) = cx.tcx.named_bound_var(lifetime.hir_id)
&& let Some(lt) = cx.args.get(&did).and_then(|arg| arg.as_lt())
{
if let Some(lt) = cx.args.get(&node_id).and_then(|p| p.as_lt()).cloned() {
return lt;
}
return lt.clone();
}
Lifetime(lifetime.ident.name)
}
Expand Down Expand Up @@ -1791,12 +1789,12 @@ fn maybe_expand_private_type_alias<'tcx>(
_ => None,
});
if let Some(lt) = lifetime {
let cleaned = if !lt.is_anonymous() {
let lt = if !lt.is_anonymous() {
clean_lifetime(lt, cx)
} else {
Lifetime::elided()
};
args.insert(param.def_id.to_def_id(), InstantiationParam::Lifetime(cleaned));
args.insert(param.def_id.to_def_id(), GenericArg::Lifetime(lt));
}
indices.lifetimes += 1;
}
Expand All @@ -1805,44 +1803,20 @@ fn maybe_expand_private_type_alias<'tcx>(
let type_ = generic_args.args.iter().find_map(|arg| match arg {
hir::GenericArg::Type(ty) => {
if indices.types == j {
return Some(ty);
return Some(*ty);
}
j += 1;
None
}
_ => None,
});
if let Some(ty) = type_ {
args.insert(
param.def_id.to_def_id(),
InstantiationParam::Type(clean_ty(ty, cx)),
);
} else if let Some(default) = *default {
args.insert(
param.def_id.to_def_id(),
InstantiationParam::Type(clean_ty(default, cx)),
);
if let Some(ty) = type_.or(*default) {
args.insert(param.def_id.to_def_id(), GenericArg::Type(clean_ty(ty, cx)));
}
indices.types += 1;
}
hir::GenericParamKind::Const { .. } => {
let mut j = 0;
let const_ = generic_args.args.iter().find_map(|arg| match arg {
hir::GenericArg::Const(ct) => {
if indices.consts == j {
return Some(ct);
}
j += 1;
None
}
_ => None,
});
if let Some(_) = const_ {
args.insert(param.def_id.to_def_id(), InstantiationParam::Constant);
}
// FIXME(const_generics_defaults)
indices.consts += 1;
}
// FIXME(#82852): Instantiate const parameters.
hir::GenericParamKind::Const { .. } => {}
}
}

Expand Down
Loading