Auto merge of #116885 - aliemjay:rollup-plbeppt, r=aliemjay

Rollup of 5 pull requests

Successful merges:

 - #116812 (Disable missing_copy_implementations lint on non_exhaustive types)
 - #116856 (Disable effects in libcore again)
 - #116865 (Suggest constraining assoc types in more cases)
 - #116870 (Don't compare host param by name)
 - #116879 (revert #114586)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2023-10-18 11:55:41 +00:00
commit e1de04ad4e
21 changed files with 271 additions and 139 deletions

View File

@ -328,26 +328,19 @@ fn check_opaque_type_well_formed<'tcx>(
// Require that the hidden type actually fulfills all the bounds of the opaque type, even without
// the bounds that the function supplies.
let mut obligations = vec![];
infcx
.insert_hidden_type(
OpaqueTypeKey { def_id, args: identity_args },
&ObligationCause::misc(definition_span, def_id),
param_env,
definition_ty,
true,
&mut obligations,
)
.unwrap();
infcx.add_item_bounds_for_hidden_type(
def_id.to_def_id(),
identity_args,
ObligationCause::misc(definition_span, def_id),
param_env,
definition_ty,
&mut obligations,
);
ocx.register_obligations(obligations);
let opaque_ty = Ty::new_opaque(tcx, def_id.to_def_id(), identity_args);
ocx.eq(&ObligationCause::misc(definition_span, def_id), param_env, opaque_ty, definition_ty)
.map_err(|err| {
infcx
.err_ctxt()
.report_mismatched_types(
&ObligationCause::misc(definition_span, def_id),
opaque_ty,
definition_ty,
err,
)
.emit()
})?;
// Require the hidden type to be well-formed with only the generics of the opaque type.
// Defining use functions may have more bounds than the opaque type, which is ok, as long as the

View File

@ -46,10 +46,11 @@ impl<'tcx> Bounds<'tcx> {
) {
self.push_trait_bound_inner(tcx, trait_ref, span, polarity);
// if we have a host param, we push an unconst trait bound in addition
// to the const one.
// FIXME(effects) we should find a better way than name matching
if tcx.features().effects && trait_ref.skip_binder().args.host_effect_param().is_some() {
// push a non-const (`host = true`) version of the bound if it is `~const`.
if tcx.features().effects
&& let Some(host_effect_idx) = tcx.generics_of(trait_ref.def_id()).host_effect_index
&& trait_ref.skip_binder().args.const_at(host_effect_idx) != tcx.consts.true_
{
let generics = tcx.generics_of(trait_ref.def_id());
let Some(host_index) = generics.host_effect_index else { return };
let trait_ref = trait_ref.map_bound(|mut trait_ref| {

View File

@ -786,8 +786,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
tcx.consts.false_
}
Some(hir::ConstContext::ConstFn) => {
let args = ty::GenericArgs::identity_for_item(tcx, context);
args.host_effect_param().expect("ConstContext::Maybe must have host effect param")
let host_idx = tcx
.generics_of(context)
.host_effect_index
.expect("ConstContext::Maybe must have host effect param");
ty::GenericArgs::identity_for_item(tcx, context).const_at(host_idx)
}
None => tcx.consts.true_,
};

View File

@ -341,39 +341,48 @@ impl<T> Trait<T> for X {
let tcx = self.tcx;
let assoc = tcx.associated_item(proj_ty.def_id);
let (trait_ref, assoc_args) = proj_ty.trait_ref_and_own_args(tcx);
if let Some(item) = tcx.hir().get_if_local(body_owner_def_id) {
if let Some(hir_generics) = item.generics() {
// Get the `DefId` for the type parameter corresponding to `A` in `<A as T>::Foo`.
// This will also work for `impl Trait`.
let def_id = if let ty::Param(param_ty) = proj_ty.self_ty().kind() {
let generics = tcx.generics_of(body_owner_def_id);
generics.type_param(param_ty, tcx).def_id
} else {
return false;
};
let Some(def_id) = def_id.as_local() else {
return false;
};
let Some(item) = tcx.hir().get_if_local(body_owner_def_id) else {
return false;
};
let Some(hir_generics) = item.generics() else {
return false;
};
// Get the `DefId` for the type parameter corresponding to `A` in `<A as T>::Foo`.
// This will also work for `impl Trait`.
let def_id = if let ty::Param(param_ty) = proj_ty.self_ty().kind() {
let generics = tcx.generics_of(body_owner_def_id);
generics.type_param(param_ty, tcx).def_id
} else {
return false;
};
let Some(def_id) = def_id.as_local() else {
return false;
};
// First look in the `where` clause, as this might be
// `fn foo<T>(x: T) where T: Trait`.
for pred in hir_generics.bounds_for_param(def_id) {
if self.constrain_generic_bound_associated_type_structured_suggestion(
diag,
&trait_ref,
pred.bounds,
assoc,
assoc_args,
ty,
&msg,
false,
) {
return true;
}
}
// First look in the `where` clause, as this might be
// `fn foo<T>(x: T) where T: Trait`.
for pred in hir_generics.bounds_for_param(def_id) {
if self.constrain_generic_bound_associated_type_structured_suggestion(
diag,
&trait_ref,
pred.bounds,
assoc,
assoc_args,
ty,
&msg,
false,
) {
return true;
}
}
false
// If associated item, look to constrain the params of the trait/impl.
let hir_id = match item {
hir::Node::ImplItem(item) => item.hir_id(),
hir::Node::TraitItem(item) => item.hir_id(),
_ => return false,
};
let parent = tcx.hir().get_parent_item(hir_id).def_id;
self.suggest_constraint(diag, msg, parent.into(), proj_ty, ty)
}
/// An associated type was expected and a different type was found.
@ -426,21 +435,26 @@ impl<T> Trait<T> for X {
let impl_comparison =
matches!(cause_code, ObligationCauseCode::CompareImplItemObligation { .. });
let assoc = tcx.associated_item(proj_ty.def_id);
if !callable_scope || impl_comparison {
if impl_comparison {
// We do not want to suggest calling functions when the reason of the
// type error is a comparison of an `impl` with its `trait` or when the
// scope is outside of a `Body`.
// type error is a comparison of an `impl` with its `trait`.
} else {
// If we find a suitable associated function that returns the expected type, we don't
// want the more general suggestion later in this method about "consider constraining
// the associated type or calling a method that returns the associated type".
let point_at_assoc_fn = self.point_at_methods_that_satisfy_associated_type(
diag,
assoc.container_id(tcx),
current_method_ident,
proj_ty.def_id,
values.expected,
);
let point_at_assoc_fn = if callable_scope
&& self.point_at_methods_that_satisfy_associated_type(
diag,
assoc.container_id(tcx),
current_method_ident,
proj_ty.def_id,
values.expected,
) {
// If we find a suitable associated function that returns the expected type, we
// don't want the more general suggestion later in this method about "consider
// constraining the associated type or calling a method that returns the associated
// type".
true
} else {
false
};
// Possibly suggest constraining the associated type to conform to the
// found type.
if self.suggest_constraint(diag, &msg, body_owner_def_id, proj_ty, values.found)

View File

@ -145,25 +145,7 @@ impl<'tcx> InferCtxt<'tcx> {
return None;
}
}
DefiningAnchor::Bubble => {
if let ty::Alias(ty::Opaque, _) = b.kind() {
// In bubble mode we don't know which of the two opaque types is supposed to have the other
// as a hidden type (both, none or either one of them could be in its defining scope).
let predicate = ty::PredicateKind::AliasRelate(
a.into(),
b.into(),
ty::AliasRelationDirection::Equate,
);
let obligation = traits::Obligation::new(
self.tcx,
cause.clone(),
param_env,
predicate,
);
let obligations = vec![obligation];
return Some(Ok(InferOk { value: (), obligations }));
}
}
DefiningAnchor::Bubble => {}
DefiningAnchor::Error => return None,
};
if let ty::Alias(ty::Opaque, ty::AliasTy { def_id: b_def_id, .. }) = *b.kind() {

View File

@ -677,6 +677,11 @@ impl<'tcx> LateLintPass<'tcx> for MissingCopyImplementations {
if type_implements_negative_copy_modulo_regions(cx.tcx, ty, param_env) {
return;
}
if def.is_variant_list_non_exhaustive()
|| def.variants().iter().any(|variant| variant.is_field_list_non_exhaustive())
{
return;
}
// We shouldn't recommend implementing `Copy` on stateful things,
// such as iterators.

View File

@ -11,7 +11,6 @@ use rustc_errors::{DiagnosticArgValue, IntoDiagnosticArg};
use rustc_hir::def_id::DefId;
use rustc_macros::HashStable;
use rustc_serialize::{self, Decodable, Encodable};
use rustc_span::sym;
use rustc_type_ir::WithCachedTypeInfo;
use smallvec::SmallVec;
@ -452,10 +451,6 @@ impl<'tcx> GenericArgs<'tcx> {
tcx.mk_args_from_iter(self.iter().take(generics.count()))
}
pub fn host_effect_param(&'tcx self) -> Option<ty::Const<'tcx>> {
self.consts().rfind(|x| matches!(x.kind(), ty::ConstKind::Param(p) if p.name == sym::host))
}
pub fn print_as_list(&self) -> String {
let v = self.iter().map(|arg| arg.to_string()).collect::<Vec<_>>();
format!("[{}]", v.join(", "))

View File

@ -6,7 +6,6 @@ use rustc_infer::infer::DefineOpaqueTypes;
use rustc_infer::traits::ProjectionCacheKey;
use rustc_infer::traits::{PolyTraitObligation, SelectionError, TraitEngine};
use rustc_middle::mir::interpret::ErrorHandled;
use rustc_middle::traits::DefiningAnchor;
use rustc_middle::ty::abstract_const::NotConstEvaluatable;
use rustc_middle::ty::error::{ExpectedFound, TypeError};
use rustc_middle::ty::GenericArgsRef;
@ -626,27 +625,9 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
}
}
ty::PredicateKind::Ambiguous => ProcessResult::Unchanged,
ty::PredicateKind::AliasRelate(..)
if matches!(self.selcx.infcx.defining_use_anchor, DefiningAnchor::Bubble) =>
{
ProcessResult::Unchanged
ty::PredicateKind::AliasRelate(..) => {
bug!("AliasRelate is only used for new solver")
}
ty::PredicateKind::AliasRelate(a, b, relate) => match relate {
ty::AliasRelationDirection::Equate => match self
.selcx
.infcx
.at(&obligation.cause, obligation.param_env)
.eq(DefineOpaqueTypes::Yes, a, b)
{
Ok(inf_ok) => ProcessResult::Changed(mk_pending(inf_ok.into_obligations())),
Err(_) => ProcessResult::Error(FulfillmentErrorCode::CodeSelectionError(
SelectionError::Unimplemented,
)),
},
ty::AliasRelationDirection::Subtype => {
bug!("AliasRelate with subtyping is only used for new solver")
}
},
ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, ty)) => {
match self.selcx.infcx.at(&obligation.cause, obligation.param_env).eq(
DefineOpaqueTypes::No,

View File

@ -38,7 +38,6 @@ use rustc_infer::traits::TraitObligation;
use rustc_middle::dep_graph::dep_kinds;
use rustc_middle::dep_graph::DepNodeIndex;
use rustc_middle::mir::interpret::ErrorHandled;
use rustc_middle::traits::DefiningAnchor;
use rustc_middle::ty::_match::MatchAgainstFreshVars;
use rustc_middle::ty::abstract_const::NotConstEvaluatable;
use rustc_middle::ty::fold::BottomUpFolder;
@ -1005,27 +1004,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
}
}
}
ty::PredicateKind::AliasRelate(..)
if matches!(self.infcx.defining_use_anchor, DefiningAnchor::Bubble) =>
{
Ok(EvaluatedToAmbig)
ty::PredicateKind::AliasRelate(..) => {
bug!("AliasRelate is only used for new solver")
}
ty::PredicateKind::AliasRelate(a, b, relate) => match relate {
ty::AliasRelationDirection::Equate => match self
.infcx
.at(&obligation.cause, obligation.param_env)
.eq(DefineOpaqueTypes::Yes, a, b)
{
Ok(inf_ok) => self.evaluate_predicates_recursively(
previous_stack,
inf_ok.into_obligations(),
),
Err(_) => Ok(EvaluatedToErr),
},
ty::AliasRelationDirection::Subtype => {
bug!("AliasRelate subtyping is only used for new solver")
}
},
ty::PredicateKind::Ambiguous => Ok(EvaluatedToAmbig),
ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, ty)) => {
match self.infcx.at(&obligation.cause, obligation.param_env).eq(

View File

@ -219,7 +219,6 @@
#![feature(doc_cfg)]
#![feature(doc_cfg_hide)]
#![feature(doc_notable_trait)]
#![feature(effects)]
#![feature(exhaustive_patterns)]
#![feature(extern_types)]
#![feature(fundamental)]

View File

@ -0,0 +1,14 @@
// run-rustfix
trait O {
type M;
}
trait U<A: O> {
const N: A::M;
}
impl<D> O for D {
type M = u8;
}
impl<C: O<M = u8>> U<C> for u16 {
const N: C::M = 4u8; //~ ERROR mismatched types
}
fn main() {}

View File

@ -0,0 +1,14 @@
// run-rustfix
trait O {
type M;
}
trait U<A: O> {
const N: A::M;
}
impl<D> O for D {
type M = u8;
}
impl<C: O> U<C> for u16 {
const N: C::M = 4u8; //~ ERROR mismatched types
}
fn main() {}

View File

@ -0,0 +1,16 @@
error[E0308]: mismatched types
--> $DIR/suggest-contraining-assoc-type-because-of-assoc-const.rs:12:21
|
LL | const N: C::M = 4u8;
| ^^^ expected associated type, found `u8`
|
= note: expected associated type `<C as O>::M`
found type `u8`
help: consider constraining the associated type `<C as O>::M` to `u8`
|
LL | impl<C: O<M = u8>> U<C> for u16 {
| ++++++++
error: aborting due to previous error
For more information about this error, try `rustc --explain E0308`.

View File

@ -0,0 +1,11 @@
//! Ensure we don't allow accessing const effect parameters from stable Rust.
fn main() {
i8::checked_sub::<true>(42, 43);
//~^ ERROR: method takes 0 generic arguments but 1 generic argument was supplied
}
const FOO: () = {
i8::checked_sub::<false>(42, 43);
//~^ ERROR: method takes 0 generic arguments but 1 generic argument was supplied
};

View File

@ -0,0 +1,19 @@
error[E0107]: method takes 0 generic arguments but 1 generic argument was supplied
--> $DIR/effect_param.rs:9:9
|
LL | i8::checked_sub::<false>(42, 43);
| ^^^^^^^^^^^--------- help: remove these generics
| |
| expected 0 generic arguments
error[E0107]: method takes 0 generic arguments but 1 generic argument was supplied
--> $DIR/effect_param.rs:4:9
|
LL | i8::checked_sub::<true>(42, 43);
| ^^^^^^^^^^^-------- help: remove these generics
| |
| expected 0 generic arguments
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0107`.

View File

@ -0,0 +1,29 @@
error: internal compiler error: no errors encountered even though `delay_span_bug` issued
error: internal compiler error: {OpaqueTypeKey { def_id: DefId(rpit::{opaque#0}), args: [] }: OpaqueTypeDecl { hidden_type: OpaqueHiddenType { span: no-location (#0), ty: Alias(Opaque, AliasTy { args: [], def_id: DefId(foo::{opaque#0}) }) } }}
|
=
error: internal compiler error: error performing ParamEnvAnd { param_env: ParamEnv { caller_bounds: [], reveal: UserFacing }, value: ProvePredicate { predicate: Binder { value: ProjectionPredicate(AliasTy { args: [FnDef(DefId(rpit), []), ()], def_id: DefId(ops::function::FnOnce::Output) }, Term::Ty(Alias(Opaque, AliasTy { args: [], def_id: DefId(foo::{opaque#0}) }))), bound_vars: [] } } }
--> $DIR/equality-in-canonical-query.rs:19:5
|
LL | same_output(foo, rpit);
| ^^^^^^^^^^^^^^^^^^^^^^
|
--> $DIR/equality-in-canonical-query.rs:19:5
|
LL | same_output(foo, rpit);
| ^^^^^^^^^^^^^^^^^^^^^^
query stack during panic:
end of query stack
error: aborting due to 3 previous errors

View File

@ -0,0 +1,23 @@
// issue: #116877
// revisions: sized clone
//[sized] check-pass
//[clone] known-bug: #108498
//[clone] failure-status: 101
//[clone] normalize-stderr-test: "DefId\(.*?\]::" -> "DefId("
//[clone] normalize-stderr-test: "(?m)note: .*$" -> ""
//[clone] normalize-stderr-test: "(?m)^ *\d+: .*\n" -> ""
//[clone] normalize-stderr-test: "(?m)^ *at .*\n" -> ""
#[cfg(sized)] fn rpit() -> impl Sized {}
#[cfg(clone)] fn rpit() -> impl Clone {}
fn same_output<Out>(_: impl Fn() -> Out, _: impl Fn() -> Out) {}
pub fn foo() -> impl Sized {
same_output(rpit, foo);
same_output(foo, rpit);
rpit()
}
fn main () {}

View File

@ -0,0 +1,25 @@
// Test for issue #116766.
// Ensure that we don't suggest impl'ing `Copy` for a type if it or at least one
// of it's variants are marked as `non_exhaustive`.
// check-pass
#![deny(missing_copy_implementations)]
#[non_exhaustive]
pub enum MyEnum {
A,
}
#[non_exhaustive]
pub struct MyStruct {
foo: usize,
}
pub enum MyEnum2 {
#[non_exhaustive]
A,
B,
}
fn main() {}

View File

@ -1,11 +1,17 @@
error: internal compiler error: no errors encountered even though `delay_span_bug` issued
error: internal compiler error: ambiguity performing ParamEnvAnd { param_env: ParamEnv { caller_bounds: [], reveal: UserFacing }, value: ProvePredicate { predicate: Binder { value: ProjectionPredicate(AliasTy { args: [FnDef(DefId(get_rpit), []), ()], def_id: DefId(ops::function::FnOnce::Output) }, Term::Ty(Alias(Opaque, AliasTy { args: [], def_id: DefId(Opaque::{opaque#0}) }))), bound_vars: [] } } }
error: internal compiler error: {OpaqueTypeKey { def_id: DefId(get_rpit::{opaque#0}), args: [] }: OpaqueTypeDecl { hidden_type: OpaqueHiddenType { span: no-location (#0), ty: Alias(Opaque, AliasTy { args: [], def_id: DefId(Opaque::{opaque#0}) }) } }}
|
=
error: internal compiler error: error performing ParamEnvAnd { param_env: ParamEnv { caller_bounds: [], reveal: UserFacing }, value: ProvePredicate { predicate: Binder { value: ProjectionPredicate(AliasTy { args: [FnDef(DefId(get_rpit), []), ()], def_id: DefId(ops::function::FnOnce::Output) }, Term::Ty(Alias(Opaque, AliasTy { args: [], def_id: DefId(Opaque::{opaque#0}) }))), bound_vars: [] } } }
--> $DIR/rpit_tait_equality_in_canonical_query.rs:28:5
|
LL | query(get_rpit);
| ^^^^^^^^^^^^^^^
|
--> $DIR/rpit_tait_equality_in_canonical_query.rs:28:5
|
LL | query(get_rpit);
@ -14,7 +20,10 @@ LL | query(get_rpit);
query stack during panic:
end of query stack
error: aborting due to 2 previous errors
error: aborting due to 3 previous errors

View File

@ -12,7 +12,7 @@
//[current] known-bug: #108498
//[current] failure-status: 101
//[current] normalize-stderr-test: "DefId\(.*?\]::" -> "DefId("
//[current] normalize-stderr-test: "(?m)^note: .*\n" -> ""
//[current] normalize-stderr-test: "(?m)note: .*$" -> ""
//[current] normalize-stderr-test: "(?m)^ *\d+: .*\n" -> ""
//[current] normalize-stderr-test: "(?m)^ *at .*\n" -> ""

View File

@ -0,0 +1,18 @@
// The canonical query `Projection(<get_rpit as FnOnce>::Output = Opaque)`
// is the *only* site that defines `Opaque` in MIR typeck.
//
// check-pass
#![feature(type_alias_impl_trait)]
type Opaque = impl Sized;
fn get_rpit() -> impl Sized {}
fn query(_: impl FnOnce() -> Opaque) {}
fn test(_: Opaque) {
query(get_rpit);
}
fn main() {}