Skip to content
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

Rollup of 16 pull requests #73528

Merged
merged 47 commits into from
Jun 20, 2020
Merged
Changes from 4 commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
b3aa5e3
add str to common types
lcnr May 28, 2020
df996e8
Make `need_type_info_err` more conservative
doctorn Jun 5, 2020
b4ddd91
Add FIXME to comment regarding local patterns
doctorn Jun 5, 2020
0a65f28
Diagnose use of incompatible sanitizers
tmiasko Jun 14, 2020
99d30da
Improve `Instance` docs
jonas-schievink Jun 14, 2020
9014df5
validator: print MIR instance on failure
jonas-schievink Jun 14, 2020
26e17ae
Remove `Adjustment::DerefMove`
jonas-schievink Jun 14, 2020
58062e1
shim.rs: improve docs a bit
jonas-schievink Jun 14, 2020
af97a11
shim.rs: call `FnPtr`, not `Self`
jonas-schievink Jun 14, 2020
4cb26ad
Add test
jonas-schievink Jun 15, 2020
5fbef22
warn against 'specialization' feature
RalfJung May 17, 2020
991dfe7
bless all
RalfJung Jun 16, 2020
d1265e7
libcore tests: use min_specialization
RalfJung Jun 16, 2020
5e13935
Clean up E0668 explanation
GuillaumeGomez Jun 16, 2020
bde1ccf
Clean up E0670 explanation
GuillaumeGomez Jun 17, 2020
936ecad
Add src/librustdoc as an alias for src/tools/rustdoc
jyn514 Jun 17, 2020
ba2ef58
Unify region variables when projecting associated types
matthewjasper Jun 16, 2020
f488dfc
Use alloc::Layout in DroplessArena API
tmiasko Jun 17, 2020
e9b0ce8
Add test for overflow when finding auto-trait impls in Rustdoc
Aaron1011 Jun 14, 2020
aa11704
Add helper method for reusing an existing interned region
matthewjasper Jun 18, 2020
0b5007e
merge coercion test folders
lcnr May 30, 2020
9b47586
update coercion docs
lcnr May 30, 2020
06a237f
coerce reborrow multi arg test
lcnr May 30, 2020
f4b2a20
Bump Rustfmt and RLS
Xanewok Jun 15, 2020
6fa7dc6
pretty/mir: const value enums with no variants
davidtwco Jun 18, 2020
2f9d338
forbid mutable references in all constants except const fns
pvdrz Jun 7, 2020
014e605
update tests
pvdrz Jun 8, 2020
1f48465
update diagnostics for &mut in constants
pvdrz Jun 15, 2020
96031e2
add new error code
pvdrz Jun 18, 2020
8f0bd5f
Update the doc for std::prelude, removing the "technical part" section
poliorcetics Jun 19, 2020
db0d70e
Refactor `try_find` a little
cuviper May 4, 2020
203305d
Rollup merge of #71420 - RalfJung:specialization-incomplete, r=matthe…
Manishearth Jun 20, 2020
5c9cd82
Rollup merge of #71899 - cuviper:try_find_map, r=dtolnay
Manishearth Jun 20, 2020
218b90f
Rollup merge of #72689 - lcnr:common_str, r=estebank
Manishearth Jun 20, 2020
c0a25be
Rollup merge of #72791 - lcnr:coerce-refactor, r=estebank
Manishearth Jun 20, 2020
dac512e
Rollup merge of #72934 - christianpoveda:mut-borrows-in-consts, r=oli…
Manishearth Jun 20, 2020
2d1bd57
Rollup merge of #73027 - doctorn:issue-72690, r=estebank
Manishearth Jun 20, 2020
17b80d9
Rollup merge of #73347 - tmiasko:incompatible-sanitizers, r=nikic
Manishearth Jun 20, 2020
fe4b485
Rollup merge of #73359 - jonas-schievink:do-the-shimmy, r=matthewjasper
Manishearth Jun 20, 2020
2dbb8b6
Rollup merge of #73399 - GuillaumeGomez:cleanup-e0668, r=Dylan-DPC
Manishearth Jun 20, 2020
2377a50
Rollup merge of #73436 - GuillaumeGomez:cleanup-e0670, r=Dylan-DPC
Manishearth Jun 20, 2020
d69d4c3
Rollup merge of #73440 - jyn514:bootstrap/build-rustdoc, r=Mark-Simul…
Manishearth Jun 20, 2020
db7203d
Rollup merge of #73442 - davidtwco:issue-72181-pretty-print-const-val…
Manishearth Jun 20, 2020
61f8c3e
Rollup merge of #73452 - matthewjasper:auto-rec, r=nikomatsakis
Manishearth Jun 20, 2020
fd1c783
Rollup merge of #73458 - tmiasko:arena-layout, r=matthewjasper
Manishearth Jun 20, 2020
7777b0b
Rollup merge of #73484 - poliorcetics:use-prelude-doc, r=sfackler
Manishearth Jun 20, 2020
3e40cca
Rollup merge of #73506 - Xanewok:update-rls, r=Xanewok
Manishearth Jun 20, 2020
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
5 changes: 3 additions & 2 deletions src/librustc_infer/infer/canonical/canonicalizer.rs
Original file line number Diff line number Diff line change
@@ -314,18 +314,19 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> {
}

ty::ReVar(vid) => {
let r = self
let resolved_vid = self
.infcx
.unwrap()
.inner
.borrow_mut()
.unwrap_region_constraints()
.opportunistic_resolve_var(self.tcx, vid);
.opportunistic_resolve_var(vid);
debug!(
"canonical: region var found with vid {:?}, \
opportunistically resolved to {:?}",
vid, r
);
let r = self.tcx.reuse_or_mk_region(r, ty::ReVar(resolved_vid));
self.canonicalize_region_mode.canonicalize_free_region(self, r)
}

17 changes: 6 additions & 11 deletions src/librustc_infer/infer/region_constraints/mod.rs
Original file line number Diff line number Diff line change
@@ -50,10 +50,10 @@ pub struct RegionConstraintStorage<'tcx> {
/// R1 <= R2 and R2 <= R1 and (b) we unify the two regions in this
/// table. You can then call `opportunistic_resolve_var` early
/// which will map R1 and R2 to some common region (i.e., either
/// R1 or R2). This is important when dropck and other such code
/// is iterating to a fixed point, because otherwise we sometimes
/// would wind up with a fresh stream of region variables that
/// have been equated but appear distinct.
/// R1 or R2). This is important when fulfillment, dropck and other such
/// code is iterating to a fixed point, because otherwise we sometimes
/// would wind up with a fresh stream of region variables that have been
/// equated but appear distinct.
pub(super) unification_table: ut::UnificationTableStorage<ty::RegionVid>,

/// a flag set to true when we perform any unifications; this is used
@@ -714,13 +714,8 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
}
}

pub fn opportunistic_resolve_var(
&mut self,
tcx: TyCtxt<'tcx>,
rid: RegionVid,
) -> ty::Region<'tcx> {
let vid = self.unification_table().probe_value(rid).min_vid;
tcx.mk_region(ty::ReVar(vid))
pub fn opportunistic_resolve_var(&mut self, rid: RegionVid) -> ty::RegionVid {
self.unification_table().probe_value(rid).min_vid
}

fn combine_map(&mut self, t: CombineMapType) -> &mut CombineMap<'tcx> {
43 changes: 24 additions & 19 deletions src/librustc_infer/infer/resolve.rs
Original file line number Diff line number Diff line change
@@ -46,51 +46,56 @@ impl<'a, 'tcx> TypeFolder<'tcx> for OpportunisticVarResolver<'a, 'tcx> {
}
}

/// The opportunistic type and region resolver is similar to the
/// opportunistic type resolver, but also opportunistically resolves
/// regions. It is useful for canonicalization.
pub struct OpportunisticTypeAndRegionResolver<'a, 'tcx> {
/// The opportunistic region resolver opportunistically resolves regions
/// variables to the variable with the least variable id. It is used when
/// normlizing projections to avoid hitting the recursion limit by creating
/// many versions of a predicate for types that in the end have to unify.
///
/// If you want to resolve type and const variables as well, call
/// [InferCtxt::resolve_vars_if_possible] first.
pub struct OpportunisticRegionResolver<'a, 'tcx> {
infcx: &'a InferCtxt<'a, 'tcx>,
}

impl<'a, 'tcx> OpportunisticTypeAndRegionResolver<'a, 'tcx> {
impl<'a, 'tcx> OpportunisticRegionResolver<'a, 'tcx> {
pub fn new(infcx: &'a InferCtxt<'a, 'tcx>) -> Self {
OpportunisticTypeAndRegionResolver { infcx }
OpportunisticRegionResolver { infcx }
}
}

impl<'a, 'tcx> TypeFolder<'tcx> for OpportunisticTypeAndRegionResolver<'a, 'tcx> {
impl<'a, 'tcx> TypeFolder<'tcx> for OpportunisticRegionResolver<'a, 'tcx> {
fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
self.infcx.tcx
}

fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
if !t.needs_infer() {
if !t.has_infer_regions() {
t // micro-optimize -- if there is nothing in this type that this fold affects...
} else {
let t0 = self.infcx.shallow_resolve(t);
t0.super_fold_with(self)
t.super_fold_with(self)
}
}

fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
match *r {
ty::ReVar(rid) => self
.infcx
.inner
.borrow_mut()
.unwrap_region_constraints()
.opportunistic_resolve_var(self.tcx(), rid),
ty::ReVar(rid) => {
let resolved = self
.infcx
.inner
.borrow_mut()
.unwrap_region_constraints()
.opportunistic_resolve_var(rid);
self.tcx().reuse_or_mk_region(r, ty::ReVar(resolved))
}
_ => r,
}
}

fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
if !ct.needs_infer() {
if !ct.has_infer_regions() {
ct // micro-optimize -- if there is nothing in this const that this fold affects...
} else {
let c0 = self.infcx.shallow_resolve(ct);
c0.super_fold_with(self)
ct.super_fold_with(self)
}
}
}
7 changes: 7 additions & 0 deletions src/librustc_middle/ty/context.rs
Original file line number Diff line number Diff line change
@@ -2110,6 +2110,13 @@ impl<'tcx> TyCtxt<'tcx> {
})
}

/// Same a `self.mk_region(kind)`, but avoids accessing the interners if
/// `*r == kind`.
#[inline]
pub fn reuse_or_mk_region(self, r: Region<'tcx>, kind: RegionKind) -> Region<'tcx> {
if *r == kind { r } else { self.mk_region(kind) }
}

#[allow(rustc::usage_of_ty_tykind)]
#[inline]
pub fn mk_ty(&self, st: TyKind<'tcx>) -> Ty<'tcx> {
3 changes: 3 additions & 0 deletions src/librustc_middle/ty/fold.rs
Original file line number Diff line number Diff line change
@@ -87,6 +87,9 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone {
fn has_param_types_or_consts(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_TY_PARAM | TypeFlags::HAS_CT_PARAM)
}
fn has_infer_regions(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_RE_INFER)
}
fn has_infer_types(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_TY_INFER)
}
12 changes: 11 additions & 1 deletion src/librustc_trait_selection/traits/project.rs
Original file line number Diff line number Diff line change
@@ -24,6 +24,7 @@ use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_errors::ErrorReported;
use rustc_hir::def_id::DefId;
use rustc_hir::lang_items::{FnOnceTraitLangItem, GeneratorTraitLangItem};
use rustc_infer::infer::resolve::OpportunisticRegionResolver;
use rustc_middle::ty::fold::{TypeFoldable, TypeFolder};
use rustc_middle::ty::subst::Subst;
use rustc_middle::ty::util::IntTypeExt;
@@ -1146,7 +1147,7 @@ fn confirm_candidate<'cx, 'tcx>(
) -> Progress<'tcx> {
debug!("confirm_candidate(candidate={:?}, obligation={:?})", candidate, obligation);

match candidate {
let mut progress = match candidate {
ProjectionTyCandidate::ParamEnv(poly_projection)
| ProjectionTyCandidate::TraitDef(poly_projection) => {
confirm_param_env_candidate(selcx, obligation, poly_projection)
@@ -1155,7 +1156,16 @@ fn confirm_candidate<'cx, 'tcx>(
ProjectionTyCandidate::Select(impl_source) => {
confirm_select_candidate(selcx, obligation, obligation_trait_ref, impl_source)
}
};
// When checking for cycle during evaluation, we compare predicates with
// "syntactic" equality. Since normalization generally introduces a type
// with new region variables, we need to resolve them to existing variables
// when possible for this to work. See `auto-trait-projection-recursion.rs`
// for a case where this matters.
if progress.ty.has_infer_regions() {
progress.ty = OpportunisticRegionResolver::new(selcx.infcx()).fold_ty(progress.ty);
}
progress
}

fn confirm_select_candidate<'cx, 'tcx>(
35 changes: 35 additions & 0 deletions src/test/rustdoc/synthetic_auto/overflow.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Tests that we don't fail with an overflow error for certain
// strange types
// See https://github.com/rust-lang/rust/pull/72936#issuecomment-643676915

pub trait Interner {
type InternedType;
}

struct RustInterner<'tcx> {
foo: &'tcx ()
}

impl<'tcx> Interner for RustInterner<'tcx> {
type InternedType = Box<TyData<Self>>;
}

enum TyData<I: Interner> {
FnDef(I::InternedType)
}

struct VariableKind<I: Interner>(I::InternedType);

// @has overflow/struct.BoundVarsCollector.html
// @has - '//code' "impl<'tcx> Send for BoundVarsCollector<'tcx>"
pub struct BoundVarsCollector<'tcx> {
val: VariableKind<RustInterner<'tcx>>
}

fn is_send<T: Send>() {}

struct MyInterner<'tcx> {
val: &'tcx ()
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
--> $DIR/project-fn-ret-invariant.rs:48:8
--> $DIR/project-fn-ret-invariant.rs:48:4
|
LL | bar(foo, x)
| ^^^
| ^^^^^^^^^^^
|
note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 44:8...
--> $DIR/project-fn-ret-invariant.rs:44:8
File renamed without changes.
34 changes: 34 additions & 0 deletions src/test/ui/auto-traits/auto-trait-projection-recursion.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Checking the `Send` bound in `main` requires:
//
// checking <C<'static> as Y>::P: Send
// which normalizes to Box<X<C<'?1>>>: Send
// which needs X<C<'?1>>: Send
// which needs <C<'?1> as Y>::P: Send
//
// At this point we used to normalize the predicate to `Box<X<C<'?2>>>: Send`
// and continue in a loop where we created new region variables to the
// recursion limit. To avoid this we now "canonicalize" region variables to
// lowest unified region vid. This means we instead have to prove
// `Box<X<C<'?1>>>: Send`, which we can because auto traits are coinductive.

// check-pass

// Avoid a really long error message if this regresses.
#![recursion_limit="20"]

trait Y {
type P;
}

impl<'a> Y for C<'a> {
type P = Box<X<C<'a>>>;
}

struct C<'a>(&'a ());
struct X<T: Y>(T::P);

fn is_send<S: Send>() {}

fn main() {
is_send::<X<C<'static>>>();
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
30 changes: 30 additions & 0 deletions src/test/ui/traits/traits-inductive-overflow-lifetime.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Test that we don't hit the recursion limit for short cycles involving lifetimes.

// Shouldn't hit this, we should realize that we're in a cycle sooner.
#![recursion_limit="20"]

trait NotAuto {}
trait Y {
type P;
}

impl<'a> Y for C<'a> {
type P = Box<X<C<'a>>>;
}

struct C<'a>(&'a ());
struct X<T: Y>(T::P);

impl<T: NotAuto> NotAuto for Box<T> {}
impl<T: Y> NotAuto for X<T> where T::P: NotAuto {}
impl<'a> NotAuto for C<'a> {}

fn is_send<S: NotAuto>() {}
//~^ NOTE: required

fn main() {
// Should only be a few notes.
is_send::<X<C<'static>>>();
//~^ ERROR overflow evaluating
//~| NOTE: required
}
14 changes: 14 additions & 0 deletions src/test/ui/traits/traits-inductive-overflow-lifetime.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
error[E0275]: overflow evaluating the requirement `std::boxed::Box<X<C<'_>>>: NotAuto`
--> $DIR/traits-inductive-overflow-lifetime.rs:27:5
|
LL | fn is_send<S: NotAuto>() {}
| ------- required by this bound in `is_send`
...
LL | is_send::<X<C<'static>>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: required because of the requirements on the impl of `NotAuto` for `X<C<'static>>`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0275`.