Auto merge of #75722 - Mark-Simulacrum:beta-next, r=Mark-Simulacrum

[beta] backports

* Fix regionck failure when converting Index to IndexMut #74960
* Update RELEASES.md for 1.46.0 #74744
* allow escaping bound vars when normalizing `ty::Opaque` #75443

r? @ghost
This commit is contained in:
bors 2020-08-21 13:32:14 +00:00
commit cfbc6d4cf1
23 changed files with 393 additions and 116 deletions

View File

@ -1,3 +1,128 @@
Version 1.46.0 (2020-08-27)
==========================
Language
--------
- [`if`, `match`, and `loop` expressions can now be used in const functions.][72437]
- [Additionally you are now also able to coerce and cast to slices (`&[T]`) in
const functions.][73862]
- [The `#[track_caller]` attribute can now be added to functions to use the
function's caller's location information for panic messages.][72445]
- [Recursively indexing into tuples no longer needs parentheses.][71322] E.g.
`x.0.0` over `(x.0).0`.
- [`mem::transmute` can now be used in static and constants.][72920] **Note**
You currently can't use `mem::transmute` in constant functions.
Compiler
--------
- [You can now use the `cdylib` target on Apple iOS and tvOS platforms.][73516]
- [Enabled static "Position Independent Executables" by default
for `x86_64-unknown-linux-musl`.][70740]
Libraries
---------
- [`mem::forget` is now a `const fn`.][73887]
- [`String` now implements `From<char>`.][73466]
- [The `leading_ones`, and `trailing_ones` methods have been stabilised for all
integer types.][73032]
- [`vec::IntoIter<T>` now implements `AsRef<[T]>`.][72583]
- [All non-zero integer types (`NonZeroU8`) now implement `TryFrom` for their
zero-able equivalent (e.g. `TryFrom<u8>`).][72717]
- [`&[T]` and `&mut [T]` now implement `PartialEq<Vec<T>>`.][71660]
- [`(String, u16)` now implements `ToSocketAddrs`.][73007]
- [`vec::Drain<'_, T>` now implements `AsRef<[T]>`.][72584]
Stabilized APIs
---------------
- [`Option::zip`]
- [`vec::Drain::as_slice`]
Cargo
-----
Added a number of new environment variables that are now available when
compiling your crate.
- [`CARGO_BIN_NAME` and `CARGO_CRATE_NAME`][cargo/8270] Providing the name of
the specific binary being compiled and the name of the crate.
- [`CARGO_PKG_LICENSE`][cargo/8325] The license from the manifest of the package.
- [`CARGO_PKG_LICENSE_FILE`][cargo/8387] The path to the license file.
Compatibility Notes
-------------------
- [The target configuration option `abi_blacklist` has been renamed
to `unsupported_abis`.][74150] The old name will still continue to work.
- [Rustc will now warn if you have a C-like enum that implements `Drop`.][72331]
This was previously accepted but will become a hard error in a future release.
- [Rustc will fail to compile if you have a struct with
`#[repr(i128)]` or `#[repr(u128)]`.][74109] This representation is currently only
allowed on `enum`s.
- [Tokens passed to `macro_rules!` are now always captured.][73293] This helps
ensure that spans have the correct information, and may cause breakage if you
were relying on receiving spans with dummy information.
- [The InnoSetup installer for Windows is no longer available.][72569] This was
a legacy installer that was replaced by a MSI installer a few years ago but
was still being built.
- [`{f32, f64}::asinh` now returns the correct values for negative numbers.][72486]
- [Rustc will no longer accept overlapping trait implementations that only
differ in how the lifetime was bound.][72493]
- [Rustc now correctly relates the lifetime of an existential associated
type.][71896] This fixes some edge cases where `rustc` would erroneously allow
you to pass a shorter lifetime than expected.
[74109]: https://github.com/rust-lang/rust/pull/74109/
[74150]: https://github.com/rust-lang/rust/pull/74150/
[73862]: https://github.com/rust-lang/rust/pull/73862/
[73887]: https://github.com/rust-lang/rust/pull/73887/
[73466]: https://github.com/rust-lang/rust/pull/73466/
[73516]: https://github.com/rust-lang/rust/pull/73516/
[73293]: https://github.com/rust-lang/rust/pull/73293/
[73007]: https://github.com/rust-lang/rust/pull/73007/
[73032]: https://github.com/rust-lang/rust/pull/73032/
[72920]: https://github.com/rust-lang/rust/pull/72920/
[72569]: https://github.com/rust-lang/rust/pull/72569/
[72583]: https://github.com/rust-lang/rust/pull/72583/
[72584]: https://github.com/rust-lang/rust/pull/72584/
[72717]: https://github.com/rust-lang/rust/pull/72717/
[72437]: https://github.com/rust-lang/rust/pull/72437/
[72445]: https://github.com/rust-lang/rust/pull/72445/
[72486]: https://github.com/rust-lang/rust/pull/72486/
[72493]: https://github.com/rust-lang/rust/pull/72493/
[72331]: https://github.com/rust-lang/rust/pull/72331/
[71896]: https://github.com/rust-lang/rust/pull/71896/
[71660]: https://github.com/rust-lang/rust/pull/71660/
[71322]: https://github.com/rust-lang/rust/pull/71322/
[70740]: https://github.com/rust-lang/rust/pull/70740/
[cargo/8270]: https://github.com/rust-lang/cargo/pull/8270/
[cargo/8325]: https://github.com/rust-lang/cargo/pull/8325/
[cargo/8387]: https://github.com/rust-lang/cargo/pull/8387/
[`Option::zip`]: https://doc.rust-lang.org/stable/std/option/enum.Option.html#method.zip
[`vec::Drain::as_slice`]: https://doc.rust-lang.org/stable/std/vec/struct.Drain.html#method.as_slice
Version 1.45.2 (2020-08-03)
==========================
* [Fix bindings in tuple struct patterns][74954]
* [Fix track_caller integration with trait objects][74784]
[74954]: https://github.com/rust-lang/rust/issues/74954
[74784]: https://github.com/rust-lang/rust/issues/74784
Version 1.45.1 (2020-07-30)
==========================
* [Fix const propagation with references.][73613]
* [rustfmt accepts rustfmt_skip in cfg_attr again.][73078]
* [Avoid spurious implicit region bound.][74509]
* [Install clippy on x.py install][74457]
[73613]: https://github.com/rust-lang/rust/pull/73613
[73078]: https://github.com/rust-lang/rust/issues/73078
[74509]: https://github.com/rust-lang/rust/pull/74509
[74457]: https://github.com/rust-lang/rust/pull/74457
Version 1.45.0 (2020-07-16)
==========================
@ -47,7 +172,7 @@ Libraries
// Prints "abcdefghijklmnopqrstuvwxyz"
```
- [`OsString` now implements `FromStr`.][71662]
- [The `saturating_neg` method as been added to all signed integer primitive
- [The `saturating_neg` method has been added to all signed integer primitive
types, and the `saturating_abs` method has been added for all integer
primitive types.][71886]
- [`Arc<T>`, `Rc<T>` now implement `From<Cow<'_, T>>`, and `Box` now
@ -82,6 +207,9 @@ Stabilized APIs
Cargo
-----
- [Cargo uses the `embed-bitcode` flag to optimize disk usage and build
time.][cargo/8066]
Misc
----
- [Rustdoc now supports strikethrough text in Markdown.][71928] E.g.
@ -97,12 +225,18 @@ Compatibility Notes
- [Rustdoc's CLI's extra error exit codes have been removed.][71900] These were
previously undocumented and not intended for public use. Rustdoc still provides
a non-zero exit code on errors.
- [Rustc's `lto` flag is incompatible with the new `embed-bitcode=no`.][71848]
This may cause issues if LTO is enabled through `RUSTFLAGS` or `cargo rustc`
flags while cargo is adding `embed-bitcode` itself. The recommended way to
control LTO is with Cargo profiles, either in `Cargo.toml` or `.cargo/config`,
or by setting `CARGO_PROFILE_<name>_LTO` in the environment.
Internals Only
--------------
- [Make clippy a git subtree instead of a git submodule][70655]
- [Unify the undo log of all snapshot types][69464]
[71848]: https://github.com/rust-lang/rust/issues/71848/
[73420]: https://github.com/rust-lang/rust/issues/73420/
[72324]: https://github.com/rust-lang/rust/pull/72324/
[71843]: https://github.com/rust-lang/rust/pull/71843/
@ -129,6 +263,7 @@ Internals Only
[69813]: https://github.com/rust-lang/rust/pull/69813/
[69464]: https://github.com/rust-lang/rust/pull/69464/
[68717]: https://github.com/rust-lang/rust/pull/68717/
[cargo/8066]: https://github.com/rust-lang/cargo/pull/8066
[`Arc::as_ptr`]: https://doc.rust-lang.org/stable/std/sync/struct.Arc.html#method.as_ptr
[`BTreeMap::remove_entry`]: https://doc.rust-lang.org/stable/std/collections/struct.BTreeMap.html#method.remove_entry
[`Rc::as_ptr`]: https://doc.rust-lang.org/stable/std/rc/struct.Rc.html#method.as_ptr

View File

@ -7,7 +7,7 @@ target="x86_64-fortanix-unknown-sgx"
install_prereq() {
curl https://apt.llvm.org/llvm-snapshot.gpg.key|apt-key add -
add-apt-repository -y 'deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic main'
add-apt-repository -y 'deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-11 main'
apt-get update
apt-get install -y --no-install-recommends \
build-essential \

View File

@ -729,7 +729,7 @@ impl AutoTraitFinder<'tcx> {
// and turn them into an explicit negative impl for our type.
debug!("Projecting and unifying projection predicate {:?}", predicate);
match poly_project_and_unify_type(select, &obligation.with(p)) {
match project::poly_project_and_unify_type(select, &obligation.with(p)) {
Err(e) => {
debug!(
"evaluate_nested_obligations: Unable to unify predicate \
@ -738,7 +738,11 @@ impl AutoTraitFinder<'tcx> {
);
return false;
}
Ok(Some(v)) => {
Ok(Err(project::InProgress)) => {
debug!("evaluate_nested_obligations: recursive projection predicate");
return false;
}
Ok(Ok(Some(v))) => {
// We only care about sub-obligations
// when we started out trying to unify
// some inference variables. See the comment above
@ -757,8 +761,8 @@ impl AutoTraitFinder<'tcx> {
}
}
}
Ok(None) => {
// It's ok not to make progress when hvave no inference variables -
Ok(Ok(None)) => {
// It's ok not to make progress when have no inference variables -
// in that case, we were only performing unifcation to check if an
// error occurred (which would indicate that it's impossible for our
// type to implement the auto trait).

View File

@ -426,14 +426,20 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
ty::PredicateKind::Projection(ref data) => {
let project_obligation = obligation.with(*data);
let tcx = self.selcx.tcx();
match project::poly_project_and_unify_type(self.selcx, &project_obligation) {
Ok(None) => {
let tcx = self.selcx.tcx();
pending_obligation.stalled_on =
trait_ref_infer_vars(self.selcx, data.to_poly_trait_ref(tcx));
Ok(Ok(Some(os))) => ProcessResult::Changed(mk_pending(os)),
Ok(Ok(None)) => {
pending_obligation.stalled_on = trait_ref_infer_vars(
self.selcx,
project_obligation.predicate.to_poly_trait_ref(tcx),
);
ProcessResult::Unchanged
}
Ok(Some(os)) => ProcessResult::Changed(mk_pending(os)),
// Let the caller handle the recursion
Ok(Err(project::InProgress)) => ProcessResult::Changed(mk_pending(vec![
pending_obligation.obligation.clone(),
])),
Err(e) => ProcessResult::Error(CodeProjectionError(e)),
}
}

View File

@ -51,9 +51,7 @@ pub use self::object_safety::is_vtable_safe_method;
pub use self::object_safety::MethodViolationCode;
pub use self::object_safety::ObjectSafetyViolation;
pub use self::on_unimplemented::{OnUnimplementedDirective, OnUnimplementedNote};
pub use self::project::{
normalize, normalize_projection_type, normalize_to, poly_project_and_unify_type,
};
pub use self::project::{normalize, normalize_projection_type, normalize_to};
pub use self::select::{EvaluationCache, SelectionCache, SelectionContext};
pub use self::select::{EvaluationResult, IntercrateAmbiguityCause, OverflowError};
pub use self::specialize::specialization_graph::FutureCompatOverlapError;

View File

@ -40,6 +40,8 @@ pub type ProjectionObligation<'tcx> = Obligation<'tcx, ty::ProjectionPredicate<'
pub type ProjectionTyObligation<'tcx> = Obligation<'tcx, ty::ProjectionTy<'tcx>>;
pub(super) struct InProgress;
/// When attempting to resolve `<T as TraitRef>::Name` ...
#[derive(Debug)]
pub enum ProjectionTyError<'tcx> {
@ -142,10 +144,26 @@ impl<'tcx> ProjectionTyCandidateSet<'tcx> {
///
/// If successful, this may result in additional obligations. Also returns
/// the projection cache key used to track these additional obligations.
pub fn poly_project_and_unify_type<'cx, 'tcx>(
///
/// ## Returns
///
/// - `Err(_)`: the projection can be normalized, but is not equal to the
/// expected type.
/// - `Ok(Err(InProgress))`: this is called recursively while normalizing
/// the same projection.
/// - `Ok(Ok(None))`: The projection cannot be normalized due to ambiguity
/// (resolving some inference variables in the projection may fix this).
/// - `Ok(Ok(Some(obligations)))`: The projection bound holds subject to
/// the given obligations. If the projection cannot be normalized because
/// the required trait bound doesn't hold this returned with `obligations`
/// being a predicate that cannot be proven.
pub(super) fn poly_project_and_unify_type<'cx, 'tcx>(
selcx: &mut SelectionContext<'cx, 'tcx>,
obligation: &PolyProjectionObligation<'tcx>,
) -> Result<Option<Vec<PredicateObligation<'tcx>>>, MismatchedProjectionTypes<'tcx>> {
) -> Result<
Result<Option<Vec<PredicateObligation<'tcx>>>, InProgress>,
MismatchedProjectionTypes<'tcx>,
> {
debug!("poly_project_and_unify_type(obligation={:?})", obligation);
let infcx = selcx.infcx();
@ -164,10 +182,15 @@ pub fn poly_project_and_unify_type<'cx, 'tcx>(
/// <T as Trait>::U == V
///
/// If successful, this may result in additional obligations.
///
/// See [poly_project_and_unify_type] for an explanation of the return value.
fn project_and_unify_type<'cx, 'tcx>(
selcx: &mut SelectionContext<'cx, 'tcx>,
obligation: &ProjectionObligation<'tcx>,
) -> Result<Option<Vec<PredicateObligation<'tcx>>>, MismatchedProjectionTypes<'tcx>> {
) -> Result<
Result<Option<Vec<PredicateObligation<'tcx>>>, InProgress>,
MismatchedProjectionTypes<'tcx>,
> {
debug!("project_and_unify_type(obligation={:?})", obligation);
let mut obligations = vec![];
@ -179,8 +202,9 @@ fn project_and_unify_type<'cx, 'tcx>(
obligation.recursion_depth,
&mut obligations,
) {
Some(n) => n,
None => return Ok(None),
Ok(Some(n)) => n,
Ok(None) => return Ok(Ok(None)),
Err(InProgress) => return Ok(Err(InProgress)),
};
debug!(
@ -195,7 +219,7 @@ fn project_and_unify_type<'cx, 'tcx>(
{
Ok(InferOk { obligations: inferred_obligations, value: () }) => {
obligations.extend(inferred_obligations);
Ok(Some(obligations))
Ok(Ok(Some(obligations)))
}
Err(err) => {
debug!("project_and_unify_type: equating types encountered error {:?}", err);
@ -323,8 +347,7 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
let ty = ty.super_fold_with(self);
match ty.kind {
ty::Opaque(def_id, substs) if !substs.has_escaping_bound_vars() => {
// (*)
ty::Opaque(def_id, substs) => {
// Only normalize `impl Trait` after type-checking, usually in codegen.
match self.param_env.reveal() {
Reveal::UserFacing => ty,
@ -352,9 +375,7 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
}
ty::Projection(ref data) if !data.has_escaping_bound_vars() => {
// (*)
// (*) This is kind of hacky -- we need to be able to
// This is kind of hacky -- we need to be able to
// handle normalization within binders because
// otherwise we wind up a need to normalize when doing
// trait matching (since you can have a trait
@ -421,6 +442,8 @@ pub fn normalize_projection_type<'a, 'b, 'tcx>(
depth,
obligations,
)
.ok()
.flatten()
.unwrap_or_else(move || {
// if we bottom out in ambiguity, create a type variable
// and a deferred predicate to resolve this when more type
@ -457,7 +480,7 @@ fn opt_normalize_projection_type<'a, 'b, 'tcx>(
cause: ObligationCause<'tcx>,
depth: usize,
obligations: &mut Vec<PredicateObligation<'tcx>>,
) -> Option<Ty<'tcx>> {
) -> Result<Option<Ty<'tcx>>, InProgress> {
let infcx = selcx.infcx();
let projection_ty = infcx.resolve_vars_if_possible(&projection_ty);
@ -489,7 +512,7 @@ fn opt_normalize_projection_type<'a, 'b, 'tcx>(
"opt_normalize_projection_type: \
found cache entry: ambiguous"
);
return None;
return Ok(None);
}
Err(ProjectionCacheEntry::InProgress) => {
// If while normalized A::B, we are asked to normalize
@ -504,24 +527,14 @@ fn opt_normalize_projection_type<'a, 'b, 'tcx>(
// to normalize `A::B`, we will want to check the
// where-clauses in scope. So we will try to unify `A::B`
// with `A::B`, which can trigger a recursive
// normalization. In that case, I think we will want this code:
//
// ```
// let ty = selcx.tcx().mk_projection(projection_ty.item_def_id,
// projection_ty.substs;
// return Some(NormalizedTy { value: v, obligations: vec![] });
// ```
// normalization.
debug!(
"opt_normalize_projection_type: \
found cache entry: in-progress"
);
// But for now, let's classify this as an overflow:
let recursion_limit = selcx.tcx().sess.recursion_limit();
let obligation =
Obligation::with_depth(cause, recursion_limit.0, param_env, projection_ty);
selcx.infcx().report_overflow_error(&obligation, false);
return Err(InProgress);
}
Err(ProjectionCacheEntry::NormalizedTy(ty)) => {
// This is the hottest path in this function.
@ -557,7 +570,7 @@ fn opt_normalize_projection_type<'a, 'b, 'tcx>(
cause,
depth,
));
return Some(ty.value);
return Ok(Some(ty.value));
}
Err(ProjectionCacheEntry::Error) => {
debug!(
@ -566,7 +579,7 @@ fn opt_normalize_projection_type<'a, 'b, 'tcx>(
);
let result = normalize_to_error(selcx, param_env, projection_ty, cause, depth);
obligations.extend(result.obligations);
return Some(result.value);
return Ok(Some(result.value));
}
}
@ -613,7 +626,7 @@ fn opt_normalize_projection_type<'a, 'b, 'tcx>(
let cache_value = prune_cache_value_obligations(infcx, &result);
infcx.inner.borrow_mut().projection_cache().insert_ty(cache_key, cache_value);
obligations.extend(result.obligations);
Some(result.value)
Ok(Some(result.value))
}
Ok(ProjectedTy::NoProgress(projected_ty)) => {
debug!(
@ -624,7 +637,7 @@ fn opt_normalize_projection_type<'a, 'b, 'tcx>(
let result = Normalized { value: projected_ty, obligations: vec![] };
infcx.inner.borrow_mut().projection_cache().insert_ty(cache_key, result.clone());
// No need to extend `obligations`.
Some(result.value)
Ok(Some(result.value))
}
Err(ProjectionTyError::TooManyCandidates) => {
debug!(
@ -632,7 +645,7 @@ fn opt_normalize_projection_type<'a, 'b, 'tcx>(
too many candidates"
);
infcx.inner.borrow_mut().projection_cache().ambiguous(cache_key);
None
Ok(None)
}
Err(ProjectionTyError::TraitSelectionError(_)) => {
debug!("opt_normalize_projection_type: ERROR");
@ -644,7 +657,7 @@ fn opt_normalize_projection_type<'a, 'b, 'tcx>(
infcx.inner.borrow_mut().projection_cache().error(cache_key);
let result = normalize_to_error(selcx, param_env, projection_ty, cause, depth);
obligations.extend(result.obligations);
Some(result.value)
Ok(Some(result.value))
}
}
}
@ -1115,11 +1128,11 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
}
super::ImplSourceAutoImpl(..) | super::ImplSourceBuiltin(..) => {
// These traits have no associated types.
span_bug!(
selcx.tcx().sess.delay_span_bug(
obligation.cause.span,
"Cannot project an associated type from `{:?}`",
impl_source
&format!("Cannot project an associated type from `{:?}`", impl_source),
);
return Err(());
}
};

View File

@ -101,8 +101,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
let ty = ty.super_fold_with(self);
match ty.kind {
ty::Opaque(def_id, substs) if !substs.has_escaping_bound_vars() => {
// (*)
ty::Opaque(def_id, substs) => {
// Only normalize `impl Trait` after type-checking, usually in codegen.
match self.param_env.reveal() {
Reveal::UserFacing => ty,
@ -140,8 +139,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
}
ty::Projection(ref data) if !data.has_escaping_bound_vars() => {
// (*)
// (*) This is kind of hacky -- we need to be able to
// This is kind of hacky -- we need to be able to
// handle normalization within binders because
// otherwise we wind up a need to normalize when doing
// trait matching (since you can have a trait

View File

@ -458,7 +458,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
&ty::PredicateKind::Projection(data) => {
let project_obligation = obligation.with(data);
match project::poly_project_and_unify_type(self, &project_obligation) {
Ok(Some(mut subobligations)) => {
Ok(Ok(Some(mut subobligations))) => {
self.add_depth(subobligations.iter_mut(), obligation.recursion_depth);
let result = self.evaluate_predicates_recursively(
previous_stack,
@ -471,7 +471,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
}
result
}
Ok(None) => Ok(EvaluatedToAmbig),
Ok(Ok(None)) => Ok(EvaluatedToAmbig),
// EvaluatedToRecur might also be acceptable here, but use
// Unknown for now because it means that we won't dismiss a
// selection candidate solely because it has a projection
// cycle. This is closest to the previous behavior of
// immediately erroring.
Ok(Err(project::InProgress)) => Ok(EvaluatedToUnknown),
Err(_) => Ok(EvaluatedToErr),
}
}

View File

@ -9,6 +9,7 @@ use rustc_middle::ty::{self, Ty};
use rustc_span::symbol::{sym, Ident};
use rustc_span::Span;
use rustc_trait_selection::autoderef::Autoderef;
use std::slice;
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// Type-check `*oprnd_expr` with `oprnd_expr` type-checked already.
@ -245,19 +246,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
match expr.kind {
hir::ExprKind::Index(ref base_expr, ref index_expr) => {
// We need to get the final type in case dereferences were needed for the trait
// to apply (#72002).
let index_expr_ty = self.tables.borrow().expr_ty_adjusted(index_expr);
self.convert_place_op_to_mutable(
PlaceOp::Index,
expr,
base_expr,
&[index_expr_ty],
);
hir::ExprKind::Index(ref base_expr, ..) => {
self.convert_place_op_to_mutable(PlaceOp::Index, expr, base_expr);
}
hir::ExprKind::Unary(hir::UnOp::UnDeref, ref base_expr) => {
self.convert_place_op_to_mutable(PlaceOp::Deref, expr, base_expr, &[]);
self.convert_place_op_to_mutable(PlaceOp::Deref, expr, base_expr);
}
_ => {}
}
@ -269,9 +262,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
op: PlaceOp,
expr: &hir::Expr<'_>,
base_expr: &hir::Expr<'_>,
arg_tys: &[Ty<'tcx>],
) {
debug!("convert_place_op_to_mutable({:?}, {:?}, {:?}, {:?})", op, expr, base_expr, arg_tys);
debug!("convert_place_op_to_mutable({:?}, {:?}, {:?})", op, expr, base_expr);
if !self.tables.borrow().is_method_call(expr) {
debug!("convert_place_op_to_mutable - builtin, nothing to do");
return;
@ -286,6 +278,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.expect("place op takes something that is not a ref")
.ty;
let arg_ty = match op {
PlaceOp::Deref => None,
PlaceOp::Index => {
// We would need to recover the `T` used when we resolve `<_ as Index<T>>::index`
// in try_index_step. This is the subst at index 1.
//
// Note: we should *not* use `expr_ty` of index_expr here because autoderef
// during coercions can cause type of index_expr to differ from `T` (#72002).
// We also could not use `expr_ty_adjusted` of index_expr because reborrowing
// during coercions can also cause type of index_expr to differ from `T`,
// which can potentially cause regionck failure (#74933).
Some(self.tables.borrow().node_substs(expr.hir_id).type_at(1))
}
};
let arg_tys = match arg_ty {
None => &[],
Some(ref ty) => slice::from_ref(ty),
};
let method = self.try_mutable_overloaded_place_op(expr.span, base_ty, arg_tys, op);
let method = match method {
Some(ok) => self.register_infer_ok_obligations(ok),

View File

@ -26,16 +26,16 @@ impl Tr for u32 {
// ...but only if this actually breaks the cycle
impl Tr for bool {
//~^ ERROR overflow evaluating the requirement
//~^ ERROR type mismatch resolving `<bool as Tr>::B == _`
type A = Box<Self::B>;
//~^ ERROR overflow evaluating the requirement
//~^ ERROR type mismatch resolving `<bool as Tr>::B == _`
}
// (the error is shown twice for some reason)
impl Tr for usize {
//~^ ERROR overflow evaluating the requirement
//~^ ERROR type mismatch resolving `<usize as Tr>::B == _`
type B = &'static Self::A;
//~^ ERROR overflow evaluating the requirement
//~^ ERROR type mismatch resolving `<usize as Tr>::A == _`
}
fn main() {

View File

@ -1,33 +1,34 @@
error[E0275]: overflow evaluating the requirement `<() as Tr>::B`
error[E0275]: overflow evaluating the requirement `<() as Tr>::B == _`
--> $DIR/defaults-cyclic-fail-1.rs:10:6
|
LL | impl Tr for () {}
| ^^
error[E0275]: overflow evaluating the requirement `<bool as Tr>::B`
error[E0271]: type mismatch resolving `<bool as Tr>::B == _`
--> $DIR/defaults-cyclic-fail-1.rs:28:6
|
LL | impl Tr for bool {
| ^^
| ^^ cyclic type of infinite size
error[E0275]: overflow evaluating the requirement `<usize as Tr>::B`
error[E0271]: type mismatch resolving `<usize as Tr>::B == _`
--> $DIR/defaults-cyclic-fail-1.rs:35:6
|
LL | impl Tr for usize {
| ^^
| ^^ cyclic type of infinite size
error[E0275]: overflow evaluating the requirement `<bool as Tr>::B`
error[E0271]: type mismatch resolving `<bool as Tr>::B == _`
--> $DIR/defaults-cyclic-fail-1.rs:30:5
|
LL | type A = Box<Self::B>;
| ^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^ cyclic type of infinite size
error[E0275]: overflow evaluating the requirement `<usize as Tr>::A`
error[E0271]: type mismatch resolving `<usize as Tr>::A == _`
--> $DIR/defaults-cyclic-fail-1.rs:37:5
|
LL | type B = &'static Self::A;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ cyclic type of infinite size
error: aborting due to 5 previous errors
For more information about this error, try `rustc --explain E0275`.
Some errors have detailed explanations: E0271, E0275.
For more information about an error, try `rustc --explain E0271`.

View File

@ -10,7 +10,7 @@ trait Tr {
// ...but is an error in any impl that doesn't override at least one of the defaults
impl Tr for () {}
//~^ ERROR overflow evaluating the requirement
//~^ ERROR type mismatch resolving `<() as Tr>::B == _`
// As soon as at least one is redefined, it works:
impl Tr for u8 {
@ -28,16 +28,16 @@ impl Tr for u32 {
// ...but only if this actually breaks the cycle
impl Tr for bool {
//~^ ERROR overflow evaluating the requirement
//~^ ERROR type mismatch resolving `<bool as Tr>::B == _`
type A = Box<Self::B>;
//~^ ERROR overflow evaluating the requirement
//~^ ERROR type mismatch resolving `<bool as Tr>::B == _`
}
// (the error is shown twice for some reason)
impl Tr for usize {
//~^ ERROR overflow evaluating the requirement
//~^ ERROR type mismatch resolving `<usize as Tr>::B == _`
type B = &'static Self::A;
//~^ ERROR overflow evaluating the requirement
//~^ ERROR type mismatch resolving `<usize as Tr>::A == _`
}
fn main() {

View File

@ -1,33 +1,33 @@
error[E0275]: overflow evaluating the requirement `<() as Tr>::B`
error[E0271]: type mismatch resolving `<() as Tr>::B == _`
--> $DIR/defaults-cyclic-fail-2.rs:12:6
|
LL | impl Tr for () {}
| ^^
| ^^ cyclic type of infinite size
error[E0275]: overflow evaluating the requirement `<bool as Tr>::B`
error[E0271]: type mismatch resolving `<bool as Tr>::B == _`
--> $DIR/defaults-cyclic-fail-2.rs:30:6
|
LL | impl Tr for bool {
| ^^
| ^^ cyclic type of infinite size
error[E0275]: overflow evaluating the requirement `<usize as Tr>::B`
error[E0271]: type mismatch resolving `<usize as Tr>::B == _`
--> $DIR/defaults-cyclic-fail-2.rs:37:6
|
LL | impl Tr for usize {
| ^^
| ^^ cyclic type of infinite size
error[E0275]: overflow evaluating the requirement `<bool as Tr>::B`
error[E0271]: type mismatch resolving `<bool as Tr>::B == _`
--> $DIR/defaults-cyclic-fail-2.rs:32:5
|
LL | type A = Box<Self::B>;
| ^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^ cyclic type of infinite size
error[E0275]: overflow evaluating the requirement `<usize as Tr>::A`
error[E0271]: type mismatch resolving `<usize as Tr>::A == _`
--> $DIR/defaults-cyclic-fail-2.rs:39:5
|
LL | type B = &'static Self::A;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ cyclic type of infinite size
error: aborting due to 5 previous errors
For more information about this error, try `rustc --explain E0275`.
For more information about this error, try `rustc --explain E0271`.

View File

@ -0,0 +1,20 @@
// Case that the fix for #74868 also allowed to compile
// check-pass
trait BoxedDsl {
type Output;
}
impl<T> BoxedDsl for T
where
T: BoxedDsl,
{
type Output = <T as BoxedDsl>::Output;
}
trait HandleUpdate {}
impl<T> HandleUpdate for T where T: BoxedDsl<Output = ()> {}
fn main() {}

View File

@ -0,0 +1,43 @@
// regression test for #74868
// check-pass
trait BoxedDsl<'a> {
type Output;
}
impl<'a, T> BoxedDsl<'a> for T
where
T: BoxedDsl<'a>,
{
type Output = <T as BoxedDsl<'a>>::Output;
}
// Showing this trait is wf requires proving
// Self: HandleUpdate
//
// The impl below is a candidate for this projection, as well as the `Self:
// HandleUpdate` bound in the environment.
// We evaluate both candidates to see if we need to consider both applicable.
// Evaluating the impl candidate requires evaluating
// <T as BoxedDsl<'static>>::Output == ()
// The above impl cause normalizing the above type normalize to itself.
//
// This previously compiled because we would generate a new region
// variable each time around the cycle, and evaluation would eventually return
// `EvaluatedToErr` from the `Self: Sized` in the impl, which would in turn
// leave the bound as the only candidate.
//
// #73452 changed this so that region variables are canonicalized when we
// normalize, which means that the projection cycle is detected before
// evaluation returns EvaluatedToErr. The cycle resulted in an error being
// emitted immediately, causing this to fail to compile.
//
// To fix this, normalization doesn't directly emit errors when it finds a
// cycle, instead letting the caller handle it. This restores the original
// behavior.
trait HandleUpdate {}
impl<T> HandleUpdate for T where T: BoxedDsl<'static, Output = ()> {}
fn main() {}

View File

@ -1,5 +1,3 @@
//~ ERROR
#![feature(optin_builtin_traits)]
#![feature(negative_impls)]

View File

@ -1,17 +1,11 @@
error[E0380]: auto traits cannot have methods or associated items
--> $DIR/issue-23080-2.rs:7:10
--> $DIR/issue-23080-2.rs:5:10
|
LL | unsafe auto trait Trait {
| ----- auto trait cannot have items
LL | type Output;
| ^^^^^^
error[E0275]: overflow evaluating the requirement `<() as Trait>::Output`
|
= note: required because of the requirements on the impl of `Trait` for `()`
= note: required because of the requirements on the impl of `Trait` for `()`
error: aborting due to previous error
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0275, E0380.
For more information about an error, try `rustc --explain E0275`.
For more information about this error, try `rustc --explain E0380`.

View File

@ -5,9 +5,9 @@ trait Foo {
struct FooStruct;
impl Foo for FooStruct {
//~^ ERROR overflow evaluating the requirement `<FooStruct as Foo>::A`
//~^ ERROR overflow evaluating the requirement `<FooStruct as Foo>::A == _`
type A = <FooStruct as Foo>::A;
//~^ ERROR overflow evaluating the requirement `<FooStruct as Foo>::A`
//~^ ERROR overflow evaluating the requirement `<FooStruct as Foo>::A == _`
}
fn main() {}

View File

@ -1,10 +1,10 @@
error[E0275]: overflow evaluating the requirement `<FooStruct as Foo>::A`
error[E0275]: overflow evaluating the requirement `<FooStruct as Foo>::A == _`
--> $DIR/issue-21946.rs:7:6
|
LL | impl Foo for FooStruct {
| ^^^
error[E0275]: overflow evaluating the requirement `<FooStruct as Foo>::A`
error[E0275]: overflow evaluating the requirement `<FooStruct as Foo>::A == _`
--> $DIR/issue-21946.rs:9:5
|
LL | type A = <FooStruct as Foo>::A;

View File

@ -1,10 +1,10 @@
error[E0275]: overflow evaluating the requirement `<GetNext<T> as Next>::Next`
error[E0275]: overflow evaluating the requirement `<GetNext<T> as Next>::Next == _`
--> $DIR/issue-23122-1.rs:7:15
|
LL | impl<T: Next> Next for GetNext<T> {
| ^^^^
error[E0275]: overflow evaluating the requirement `<GetNext<T> as Next>::Next`
error[E0275]: overflow evaluating the requirement `<GetNext<T> as Next>::Next == _`
--> $DIR/issue-23122-1.rs:9:5
|
LL | type Next = <GetNext<T> as Next>::Next;

View File

@ -0,0 +1,13 @@
// build-pass
// This used to fail MIR validation due to the types on both sides of
// an assignment not being equal.
// The failure doesn't occur with a check-only build.
fn iter_slice<'a, T>(xs: &'a [T]) -> impl Iterator<Item = &'a T> {
xs.iter()
}
fn main() {
iter_slice::<()> as fn(_) -> _;
}

View File

@ -0,0 +1,38 @@
// check-pass
//
// rust-lang/rust#74933: Lifetime error when indexing with borrowed index
use std::ops::{Index, IndexMut};
struct S(V);
struct K<'a>(&'a ());
struct V;
impl<'a> Index<&'a K<'a>> for S {
type Output = V;
fn index(&self, _: &'a K<'a>) -> &V {
&self.0
}
}
impl<'a> IndexMut<&'a K<'a>> for S {
fn index_mut(&mut self, _: &'a K<'a>) -> &mut V {
&mut self.0
}
}
impl V {
fn foo(&mut self) {}
}
fn test(s: &mut S, k: &K<'_>) {
s[k] = V;
s[k].foo();
}
fn main() {
let mut s = S(V);
let k = K(&());
test(&mut s, &k);
}

View File

@ -32,8 +32,7 @@ MAINTAINERS = {
'reference': {'steveklabnik', 'Havvy', 'matthewjasper', 'ehuss'},
'rust-by-example': {'steveklabnik', 'marioidival'},
'embedded-book': {
'adamgreig', 'andre-richter', 'jamesmunns', 'korken89',
'ryankurte', 'thejpster', 'therealprof',
'adamgreig', 'andre-richter', 'jamesmunns', 'therealprof',
},
'edition-guide': {'ehuss', 'steveklabnik'},
'rustc-dev-guide': {'mark-i-m', 'spastorino', 'amanjeev', 'JohnTitor'},