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
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
@@ -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 = || {
@@ -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.
@@ -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
48 changes: 20 additions & 28 deletions compiler/rustc_infer/src/infer/at.rs
Original file line number Diff line number Diff line change
@@ -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
@@ -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")]
@@ -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")]
@@ -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 })
}
}

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
@@ -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 })
}
}

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
@@ -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) => (),
@@ -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) => (),
Original file line number Diff line number Diff line change
@@ -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,
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
@@ -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() {
@@ -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.
6 changes: 3 additions & 3 deletions library/std/src/process.rs
Original file line number Diff line number Diff line change
@@ -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();
/// ```
///
@@ -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();
/// ```
///
@@ -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();
/// ```
///
52 changes: 13 additions & 39 deletions src/librustdoc/clean/mod.rs
Original file line number Diff line number Diff line change
@@ -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)
}
@@ -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;
}
@@ -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 { .. } => {}
}
}

39 changes: 10 additions & 29 deletions src/librustdoc/clean/types.rs
Original file line number Diff line number Diff line change
@@ -2228,6 +2228,16 @@ pub(crate) enum GenericArg {
Infer,
}

impl GenericArg {
pub(crate) fn as_lt(&self) -> Option<&Lifetime> {
if let Self::Lifetime(lt) = self { Some(lt) } else { None }
}

pub(crate) fn as_ty(&self) -> Option<&Type> {
if let Self::Type(ty) = self { Some(ty) } else { None }
}
}

#[derive(Clone, PartialEq, Eq, Debug, Hash)]
pub(crate) enum GenericArgs {
AngleBracketed { args: Box<[GenericArg]>, bindings: ThinVec<TypeBinding> },
@@ -2530,35 +2540,6 @@ pub(crate) enum TypeBindingKind {
Constraint { bounds: Vec<GenericBound> },
}

/// The type, lifetime, or constant that a private type alias's parameter should be
/// replaced with when expanding a use of that type alias.
///
/// For example:
///
/// ```
/// type PrivAlias<T> = Vec<T>;
///
/// pub fn public_fn() -> PrivAlias<i32> { vec![] }
/// ```
///
/// `public_fn`'s docs will show it as returning `Vec<i32>`, since `PrivAlias` is private.
/// [`InstantiationParam`] is used to record that `T` should be mapped to `i32`.
pub(crate) enum InstantiationParam {
Type(Type),
Lifetime(Lifetime),
Constant,
}

impl InstantiationParam {
pub(crate) fn as_ty(&self) -> Option<&Type> {
if let Self::Type(ty) = self { Some(ty) } else { None }
}

pub(crate) fn as_lt(&self) -> Option<&Lifetime> {
if let Self::Lifetime(lt) = self { Some(lt) } else { None }
}
}

// Some nodes are used a lot. Make sure they don't unintentionally get bigger.
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
mod size_asserts {
13 changes: 8 additions & 5 deletions src/librustdoc/core.rs
Original file line number Diff line number Diff line change
@@ -44,10 +44,13 @@ pub(crate) struct DocContext<'tcx> {
/// Used while populating `external_traits` to ensure we don't process the same trait twice at
/// the same time.
pub(crate) active_extern_traits: DefIdSet,
// The current set of parameter instantiations,
// for expanding type aliases at the HIR level:
/// Table `DefId` of type, lifetime, or const parameter -> instantiated type, lifetime, or const
pub(crate) args: DefIdMap<clean::InstantiationParam>,
/// The current set of parameter instantiations for expanding type aliases at the HIR level.
///
/// Maps from the `DefId` of a lifetime or type parameter to the
/// generic argument it's currently instantiated to in this context.
// FIXME(#82852): We don't record const params since we don't visit const exprs at all and
// therefore wouldn't use the corresp. generic arg anyway. Add support for them.
pub(crate) args: DefIdMap<clean::GenericArg>,
pub(crate) current_type_aliases: DefIdMap<usize>,
/// Table synthetic type parameter for `impl Trait` in argument position -> bounds
pub(crate) impl_trait_bounds: FxHashMap<ImplTraitParam, Vec<clean::GenericBound>>,
@@ -87,7 +90,7 @@ impl<'tcx> DocContext<'tcx> {
/// the generic parameters for a type alias' RHS.
pub(crate) fn enter_alias<F, R>(
&mut self,
args: DefIdMap<clean::InstantiationParam>,
args: DefIdMap<clean::GenericArg>,
def_id: DefId,
f: F,
) -> R
12 changes: 6 additions & 6 deletions tests/ui/asm/inline-syntax.arm.stderr
Original file line number Diff line number Diff line change
@@ -13,7 +13,7 @@ LL | .intel_syntax noprefix
| ^

error: unknown directive
--> $DIR/inline-syntax.rs:38:15
--> $DIR/inline-syntax.rs:35:15
|
LL | asm!(".intel_syntax noprefix", "nop");
| ^
@@ -25,7 +25,7 @@ LL | .intel_syntax noprefix
| ^

error: unknown directive
--> $DIR/inline-syntax.rs:42:15
--> $DIR/inline-syntax.rs:39:15
|
LL | asm!(".intel_syntax aaa noprefix", "nop");
| ^
@@ -37,7 +37,7 @@ LL | .intel_syntax aaa noprefix
| ^

error: unknown directive
--> $DIR/inline-syntax.rs:46:15
--> $DIR/inline-syntax.rs:43:15
|
LL | asm!(".att_syntax noprefix", "nop");
| ^
@@ -49,7 +49,7 @@ LL | .att_syntax noprefix
| ^

error: unknown directive
--> $DIR/inline-syntax.rs:50:15
--> $DIR/inline-syntax.rs:47:15
|
LL | asm!(".att_syntax bbb noprefix", "nop");
| ^
@@ -61,7 +61,7 @@ LL | .att_syntax bbb noprefix
| ^

error: unknown directive
--> $DIR/inline-syntax.rs:54:15
--> $DIR/inline-syntax.rs:51:15
|
LL | asm!(".intel_syntax noprefix; nop");
| ^
@@ -73,7 +73,7 @@ LL | .intel_syntax noprefix; nop
| ^

error: unknown directive
--> $DIR/inline-syntax.rs:61:13
--> $DIR/inline-syntax.rs:58:13
|
LL | .intel_syntax noprefix
| ^
5 changes: 1 addition & 4 deletions tests/ui/asm/inline-syntax.rs
Original file line number Diff line number Diff line change
@@ -2,14 +2,11 @@
//[x86_64] compile-flags: --target x86_64-unknown-linux-gnu
//[x86_64] check-pass
//[x86_64] needs-llvm-components: x86
//[x86_64_allowed] compile-flags: --target x86_64-unknown-linux-gnu
//[x86_64_allowed] check-pass
//[x86_64_allowed] needs-llvm-components: x86
//[arm] compile-flags: --target armv7-unknown-linux-gnueabihf
//[arm] build-fail
//[arm] needs-llvm-components: arm
//[arm] ignore-llvm-version: 18 - 99
// Newer LLVM produces extra error notes.
//Newer LLVM produces extra error notes.
//[arm_llvm_18] compile-flags: --target armv7-unknown-linux-gnueabihf
//[arm_llvm_18] build-fail
//[arm_llvm_18] needs-llvm-components: arm
14 changes: 7 additions & 7 deletions tests/ui/asm/inline-syntax.x86_64.stderr
Original file line number Diff line number Diff line change
@@ -1,43 +1,43 @@
warning: avoid using `.intel_syntax`, Intel syntax is the default
--> $DIR/inline-syntax.rs:70:14
--> $DIR/inline-syntax.rs:67:14
|
LL | global_asm!(".intel_syntax noprefix", "nop");
| ^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(bad_asm_style)]` on by default

warning: avoid using `.intel_syntax`, Intel syntax is the default
--> $DIR/inline-syntax.rs:38:15
--> $DIR/inline-syntax.rs:35:15
|
LL | asm!(".intel_syntax noprefix", "nop");
| ^^^^^^^^^^^^^^^^^^^^^^

warning: avoid using `.intel_syntax`, Intel syntax is the default
--> $DIR/inline-syntax.rs:42:15
--> $DIR/inline-syntax.rs:39:15
|
LL | asm!(".intel_syntax aaa noprefix", "nop");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^

warning: avoid using `.att_syntax`, prefer using `options(att_syntax)` instead
--> $DIR/inline-syntax.rs:46:15
--> $DIR/inline-syntax.rs:43:15
|
LL | asm!(".att_syntax noprefix", "nop");
| ^^^^^^^^^^^^^^^^^^^^

warning: avoid using `.att_syntax`, prefer using `options(att_syntax)` instead
--> $DIR/inline-syntax.rs:50:15
--> $DIR/inline-syntax.rs:47:15
|
LL | asm!(".att_syntax bbb noprefix", "nop");
| ^^^^^^^^^^^^^^^^^^^^^^^^

warning: avoid using `.intel_syntax`, Intel syntax is the default
--> $DIR/inline-syntax.rs:54:15
--> $DIR/inline-syntax.rs:51:15
|
LL | asm!(".intel_syntax noprefix; nop");
| ^^^^^^^^^^^^^^^^^^^^^^

warning: avoid using `.intel_syntax`, Intel syntax is the default
--> $DIR/inline-syntax.rs:61:13
--> $DIR/inline-syntax.rs:58:13
|
LL | .intel_syntax noprefix
| ^^^^^^^^^^^^^^^^^^^^^^
18 changes: 18 additions & 0 deletions tests/ui/borrowck/copy-suggestion-region-vid.fixed
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// run-rustfix
pub struct DataStruct();

pub struct HelperStruct<'n> {
pub helpers: [Vec<&'n i64>; 2],
pub is_empty: bool,
}

impl DataStruct {
pub fn f(&self) -> HelperStruct {
let helpers = [vec![], vec![]];

HelperStruct { helpers: helpers.clone(), is_empty: helpers[0].is_empty() }
//~^ ERROR borrow of moved value
}
}

fn main() {}
2 changes: 1 addition & 1 deletion tests/ui/borrowck/copy-suggestion-region-vid.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//@run-rustfix
// run-rustfix
pub struct DataStruct();

pub struct HelperStruct<'n> {
Original file line number Diff line number Diff line change
@@ -9,8 +9,8 @@ LL | |
LL | | });
| |______^ expected due to this
|
= note: expected closure signature `fn(_, _) -> _`
found closure signature `fn(u32, i32) -> _`
= note: expected closure signature `fn(_, u32) -> _`
found closure signature `fn(_, i32) -> _`
note: required by a bound in `with_closure`
--> $DIR/expect-infer-var-appearing-twice.rs:2:14
|
27 changes: 27 additions & 0 deletions tests/ui/nll/check-normalized-sig-for-wf.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// <https://github.com/rust-lang/rust/issues/114936>
fn whoops(
s: String,
f: impl for<'s> FnOnce(&'s str) -> (&'static str, [&'static &'s (); 0]),
) -> &'static str
{
f(&s).0
//~^ ERROR `s` does not live long enough
}

// <https://github.com/rust-lang/rust/issues/118876>
fn extend<T>(input: &T) -> &'static T {
struct Bounded<'a, 'b: 'static, T>(&'a T, [&'b (); 0]);
let n: Box<dyn FnOnce(&T) -> Bounded<'static, '_, T>> = Box::new(|x| Bounded(x, []));
n(input).0
//~^ ERROR borrowed data escapes outside of function
}

// <https://github.com/rust-lang/rust/issues/118876>
fn extend_mut<'a, T>(input: &'a mut T) -> &'static mut T {
struct Bounded<'a, 'b: 'static, T>(&'a mut T, [&'b (); 0]);
let mut n: Box<dyn FnMut(&mut T) -> Bounded<'static, '_, T>> = Box::new(|x| Bounded(x, []));
n(input).0
//~^ ERROR borrowed data escapes outside of function
}

fn main() {}
47 changes: 47 additions & 0 deletions tests/ui/nll/check-normalized-sig-for-wf.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
error[E0597]: `s` does not live long enough
--> $DIR/check-normalized-sig-for-wf.rs:7:7
|
LL | s: String,
| - binding `s` declared here
...
LL | f(&s).0
| --^^-
| | |
| | borrowed value does not live long enough
| argument requires that `s` is borrowed for `'static`
LL |
LL | }
| - `s` dropped here while still borrowed

error[E0521]: borrowed data escapes outside of function
--> $DIR/check-normalized-sig-for-wf.rs:15:5
|
LL | fn extend<T>(input: &T) -> &'static T {
| ----- - let's call the lifetime of this reference `'1`
| |
| `input` is a reference that is only valid in the function body
...
LL | n(input).0
| ^^^^^^^^
| |
| `input` escapes the function body here
| argument requires that `'1` must outlive `'static`

error[E0521]: borrowed data escapes outside of function
--> $DIR/check-normalized-sig-for-wf.rs:23:5
|
LL | fn extend_mut<'a, T>(input: &'a mut T) -> &'static mut T {
| -- ----- `input` is a reference that is only valid in the function body
| |
| lifetime `'a` defined here
...
LL | n(input).0
| ^^^^^^^^
| |
| `input` escapes the function body here
| argument requires that `'a` must outlive `'static`

error: aborting due to 3 previous errors

Some errors have detailed explanations: E0521, E0597.
For more information about an error, try `rustc --explain E0521`.
Original file line number Diff line number Diff line change
@@ -20,5 +20,5 @@ default impl<T> Foo for T {

fn main() {
println!("{}", MyStruct.foo_one());
//~^ ERROR the method
//~^ ERROR no method named `foo_one` found for struct `MyStruct` in the current scope
}
Original file line number Diff line number Diff line change
@@ -8,27 +8,15 @@ LL | #![feature(specialization)]
= help: consider using `min_specialization` instead, which is more stable and complete
= note: `#[warn(incomplete_features)]` on by default

error[E0599]: the method `foo_one` exists for struct `MyStruct`, but its trait bounds were not satisfied
error[E0599]: no method named `foo_one` found for struct `MyStruct` in the current scope
--> $DIR/specialization-trait-not-implemented.rs:22:29
|
LL | struct MyStruct;
| --------------- method `foo_one` not found for this struct because it doesn't satisfy `MyStruct: Foo`
| --------------- method `foo_one` not found for this struct
...
LL | println!("{}", MyStruct.foo_one());
| ^^^^^^^ method cannot be called on `MyStruct` due to unsatisfied trait bounds
| ^^^^^^^ method not found in `MyStruct`
|
note: trait bound `MyStruct: Foo` was not satisfied
--> $DIR/specialization-trait-not-implemented.rs:14:1
|
LL | default impl<T> Foo for T {
| ^^^^^^^^^^^^^^^^---^^^^^-
| |
| unsatisfied trait bound introduced here
note: the trait `Foo` must be implemented
--> $DIR/specialization-trait-not-implemented.rs:7:1
|
LL | trait Foo {
| ^^^^^^^^^
= help: items from traits can only be used if the trait is implemented and in scope
note: `Foo` defines an item `foo_one`, perhaps you need to implement it
--> $DIR/specialization-trait-not-implemented.rs:7:1
1 change: 1 addition & 0 deletions tests/ui/specialization/defaultimpl/validation.rs
Original file line number Diff line number Diff line change
@@ -7,6 +7,7 @@ struct Z;
default impl S {} //~ ERROR inherent impls cannot be `default`

default unsafe impl Send for S {} //~ ERROR impls of auto traits cannot be default
//~^ ERROR `S` cannot be sent between threads safely
default impl !Send for Z {} //~ ERROR impls of auto traits cannot be default
//~^ ERROR negative impls cannot be default impls

22 changes: 17 additions & 5 deletions tests/ui/specialization/defaultimpl/validation.stderr
Original file line number Diff line number Diff line change
@@ -26,26 +26,38 @@ LL | default unsafe impl Send for S {}
| |
| default because of this

error[E0277]: `S` cannot be sent between threads safely
--> $DIR/validation.rs:9:1
|
LL | default unsafe impl Send for S {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `S` cannot be sent between threads safely
|
= help: the trait `Send` is not implemented for `S`
= help: the trait `Send` is implemented for `S`
= help: see issue #48214
= help: add `#![feature(trivial_bounds)]` to the crate attributes to enable

error: impls of auto traits cannot be default
--> $DIR/validation.rs:10:15
--> $DIR/validation.rs:11:15
|
LL | default impl !Send for Z {}
| ------- ^^^^ auto trait
| |
| default because of this

error[E0750]: negative impls cannot be default impls
--> $DIR/validation.rs:10:1
--> $DIR/validation.rs:11:1
|
LL | default impl !Send for Z {}
| ^^^^^^^ ^

error[E0750]: negative impls cannot be default impls
--> $DIR/validation.rs:14:1
--> $DIR/validation.rs:15:1
|
LL | default impl !Tr for S {}
| ^^^^^^^ ^

error: aborting due to 5 previous errors; 1 warning emitted
error: aborting due to 6 previous errors; 1 warning emitted

For more information about this error, try `rustc --explain E0750`.
Some errors have detailed explanations: E0277, E0750.
For more information about an error, try `rustc --explain E0277`.
16 changes: 7 additions & 9 deletions tests/ui/specialization/issue-45814.current.stderr
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
error[E0275]: overflow evaluating the requirement `T: Trait<_>`
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_45814`)
note: required for `T` to implement `Trait<_>`
--> $DIR/issue-45814.rs:9:20
error[E0119]: conflicting implementations of trait `Trait<_>`
--> $DIR/issue-45814.rs:10:1
|
LL | default impl<T, U> Trait<T> for U {}
| ^^^^^^^^ ^
= note: 128 redundant requirements hidden
= note: required for `T` to implement `Trait<_>`
| --------------------------------- first implementation here
LL |
LL | impl<T> Trait<<T as Iterator>::Item> for T {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0275`.
For more information about this error, try `rustc --explain E0119`.
16 changes: 7 additions & 9 deletions tests/ui/specialization/issue-45814.negative.stderr
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
error[E0275]: overflow evaluating the requirement `T: Trait<_>`
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_45814`)
note: required for `T` to implement `Trait<_>`
--> $DIR/issue-45814.rs:9:20
error[E0119]: conflicting implementations of trait `Trait<_>`
--> $DIR/issue-45814.rs:10:1
|
LL | default impl<T, U> Trait<T> for U {}
| ^^^^^^^^ ^
= note: 128 redundant requirements hidden
= note: required for `T` to implement `Trait<_>`
| --------------------------------- first implementation here
LL |
LL | impl<T> Trait<<T as Iterator>::Item> for T {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0275`.
For more information about this error, try `rustc --explain E0119`.
2 changes: 1 addition & 1 deletion tests/ui/specialization/issue-45814.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
//~ ERROR overflow evaluating the requirement `T: Trait<_>`
// revisions: current negative
#![feature(specialization)]
#![cfg_attr(negative, feature(with_negative_coherence))]
@@ -9,5 +8,6 @@ pub trait Trait<T> {}
default impl<T, U> Trait<T> for U {}

impl<T> Trait<<T as Iterator>::Item> for T {}
//~^ ERROR conflicting implementations of trait `Trait<_>`

fn main() {}
2 changes: 1 addition & 1 deletion triagebot.toml
Original file line number Diff line number Diff line change
@@ -651,6 +651,7 @@ compiler-team = [
"@petrochenkov",
"@davidtwco",
"@estebank",
"@lcnr",
"@oli-obk",
"@pnkfelix",
"@wesleywiser",
@@ -680,7 +681,6 @@ infra-ci = [
"@Kobzol",
]
rustdoc = [
"@jsha",
"@GuillaumeGomez",
"@notriddle",
"@fmease",