Skip to content
Merged
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
98a11e0
Remove closure_tree
camsteffen Apr 19, 2021
c9c14d0
Small refactor
camsteffen Apr 19, 2021
a10d01b
Uses flex to fix formatting of h1 at any width.
Apr 20, 2021
ba3d22e
Precompute inverse binder depth
jackh726 Apr 12, 2021
32942ab
A non-minimal set of TraitRefBoundarys to work on removing from_poly_…
jackh726 Apr 12, 2021
457c4c1
Add BinderScopeType to replace binder_depth and from_poly_trait_ref
jackh726 Apr 13, 2021
9891582
Remove TraitRefHackInner and use the concatenating functionality inst…
jackh726 Apr 20, 2021
75732dd
Check for intrinsics before coercing to a function pointer
tmiasko Apr 21, 2021
4568e7d
Move nested quantification check to ast_validation
jackh726 Apr 21, 2021
e34f7e6
Update LLVM submodule
Amanieu Apr 21, 2021
b78c0d8
Review comments
jackh726 Apr 21, 2021
eb9b0f6
Move `sys_common::rwlock::StaticRWLock` etc. to `sys::unix::rwlock`
CDirkx Apr 21, 2021
c78724f
More review changes
jackh726 Apr 21, 2021
bb91805
Replaced flex gap with margin, for compatibility with older browsers.
Apr 21, 2021
1a6de84
Remove `sys::args::Args::inner_debug` and use `Debug` instead
CDirkx Apr 21, 2021
2f438e3
Rollup merge of #84343 - camsteffen:closure-tree, r=varkor
Dylan-DPC Apr 22, 2021
7b6fd61
Rollup merge of #84376 - torhovland:issue-84534, r=GuillaumeGomez
Dylan-DPC Apr 22, 2021
9b432e0
Rollup merge of #84377 - jackh726:binder-refactor-fix, r=nikomatsakis
Dylan-DPC Apr 22, 2021
54af84b
Rollup merge of #84396 - Amanieu:fix_compiler_builtins_llvm, r=cuviper
Dylan-DPC Apr 22, 2021
aac5125
Rollup merge of #84402 - CDirkx:rwlock, r=dtolnay
Dylan-DPC Apr 22, 2021
f180c1e
Rollup merge of #84404 - tmiasko:intrinsics-in-coercion-lub, r=Mark-S…
Dylan-DPC Apr 22, 2021
d1f5fc6
Rollup merge of #84413 - CDirkx:args_inner_debug, r=m-ou-se
Dylan-DPC Apr 22, 2021
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
45 changes: 35 additions & 10 deletions compiler/rustc_ast_passes/src/ast_validation.rs
Original file line number Diff line number Diff line change
@@ -1213,8 +1213,41 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
deny_equality_constraints(self, predicate, generics);
}
}

visit::walk_generics(self, generics)
walk_list!(self, visit_generic_param, &generics.params);
for predicate in &generics.where_clause.predicates {
match predicate {
WherePredicate::BoundPredicate(bound_pred) => {
// A type binding, eg `for<'c> Foo: Send+Clone+'c`
self.check_late_bound_lifetime_defs(&bound_pred.bound_generic_params);

// This is slightly complicated. Our representation for poly-trait-refs contains a single
// binder and thus we only allow a single level of quantification. However,
// the syntax of Rust permits quantification in two places in where clauses,
// e.g., `T: for <'a> Foo<'a>` and `for <'a, 'b> &'b T: Foo<'a>`. If both are
// defined, then error.
if !bound_pred.bound_generic_params.is_empty() {
for bound in &bound_pred.bounds {
match bound {
GenericBound::Trait(t, _) => {
if !t.bound_generic_params.is_empty() {
struct_span_err!(
self.err_handler(),
t.span,
E0316,
"nested quantification of lifetimes"
)
.emit();
}
}
GenericBound::Outlives(_) => {}
}
}
}
}
_ => {}
}
self.visit_where_predicate(predicate);
}
}

fn visit_generic_param(&mut self, param: &'a GenericParam) {
@@ -1263,14 +1296,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
visit::walk_pat(self, pat)
}

fn visit_where_predicate(&mut self, p: &'a WherePredicate) {
if let &WherePredicate::BoundPredicate(ref bound_predicate) = p {
// A type binding, eg `for<'c> Foo: Send+Clone+'c`
self.check_late_bound_lifetime_defs(&bound_predicate.bound_generic_params);
}
visit::walk_where_predicate(self, p);
}

fn visit_poly_trait_ref(&mut self, t: &'a PolyTraitRef, m: &'a TraitBoundModifier) {
self.check_late_bound_lifetime_defs(&t.bound_generic_params);
visit::walk_poly_trait_ref(self, t, m);
31 changes: 0 additions & 31 deletions compiler/rustc_middle/src/middle/region.rs
Original file line number Diff line number Diff line change
@@ -235,18 +235,6 @@ pub struct ScopeTree {
/// escape into 'static and should have no local cleanup scope.
rvalue_scopes: FxHashMap<hir::ItemLocalId, Option<Scope>>,

/// Encodes the hierarchy of fn bodies. Every fn body (including
/// closures) forms its own distinct region hierarchy, rooted in
/// the block that is the fn body. This map points from the ID of
/// that root block to the ID of the root block for the enclosing
/// fn, if any. Thus the map structures the fn bodies into a
/// hierarchy based on their lexical mapping. This is used to
/// handle the relationships between regions in a fn and in a
/// closure defined by that fn. See the "Modeling closures"
/// section of the README in infer::region_constraints for
/// more details.
closure_tree: FxHashMap<hir::ItemLocalId, hir::ItemLocalId>,

/// If there are any `yield` nested within a scope, this map
/// stores the `Span` of the last one and its index in the
/// postorder of the Visitor traversal on the HIR.
@@ -356,23 +344,6 @@ impl ScopeTree {
self.destruction_scopes.get(&n).cloned()
}

/// Records that `sub_closure` is defined within `sup_closure`. These IDs
/// should be the ID of the block that is the fn body, which is
/// also the root of the region hierarchy for that fn.
pub fn record_closure_parent(
&mut self,
sub_closure: hir::ItemLocalId,
sup_closure: hir::ItemLocalId,
) {
debug!(
"record_closure_parent(sub_closure={:?}, sup_closure={:?})",
sub_closure, sup_closure
);
assert!(sub_closure != sup_closure);
let previous = self.closure_tree.insert(sub_closure, sup_closure);
assert!(previous.is_none());
}

pub fn record_var_scope(&mut self, var: hir::ItemLocalId, lifetime: Scope) {
debug!("record_var_scope(sub={:?}, sup={:?})", var, lifetime);
assert!(var != lifetime.item_local_id());
@@ -474,7 +445,6 @@ impl<'a> HashStable<StableHashingContext<'a>> for ScopeTree {
ref var_map,
ref destruction_scopes,
ref rvalue_scopes,
ref closure_tree,
ref yield_in_scope,
} = *self;

@@ -488,7 +458,6 @@ impl<'a> HashStable<StableHashingContext<'a>> for ScopeTree {
var_map.hash_stable(hcx, hasher);
destruction_scopes.hash_stable(hcx, hasher);
rvalue_scopes.hash_stable(hcx, hasher);
closure_tree.hash_stable(hcx, hasher);
yield_in_scope.hash_stable(hcx, hasher);
}
}
15 changes: 1 addition & 14 deletions compiler/rustc_passes/src/region.rs
Original file line number Diff line number Diff line change
@@ -23,14 +23,6 @@ use std::mem;

#[derive(Debug, Copy, Clone)]
pub struct Context {
/// The root of the current region tree. This is typically the id
/// of the innermost fn body. Each fn forms its own disjoint tree
/// in the region hierarchy. These fn bodies are themselves
/// arranged into a tree. See the "Modeling closures" section of
/// the README in `rustc_trait_selection::infer::region_constraints`
/// for more details.
root_id: Option<hir::ItemLocalId>,

/// The scope that contains any new variables declared, plus its depth in
/// the scope tree.
var_parent: Option<(Scope, ScopeDepth)>,
@@ -743,11 +735,6 @@ impl<'tcx> Visitor<'tcx> for RegionResolutionVisitor<'tcx> {
let outer_pessimistic_yield = mem::replace(&mut self.pessimistic_yield, false);
self.terminating_scopes.insert(body.value.hir_id.local_id);

if let Some(root_id) = self.cx.root_id {
self.scope_tree.record_closure_parent(body.value.hir_id.local_id, root_id);
}
self.cx.root_id = Some(body.value.hir_id.local_id);

self.enter_scope(Scope { id: body.value.hir_id.local_id, data: ScopeData::CallSite });
self.enter_scope(Scope { id: body.value.hir_id.local_id, data: ScopeData::Arguments });

@@ -824,7 +811,7 @@ fn region_scope_tree(tcx: TyCtxt<'_>, def_id: DefId) -> &ScopeTree {
tcx,
scope_tree: ScopeTree::default(),
expr_and_pat_count: 0,
cx: Context { root_id: None, parent: None, var_parent: None },
cx: Context { parent: None, var_parent: None },
terminating_scopes: Default::default(),
pessimistic_yield: false,
fixup_scopes: vec![],
631 changes: 219 additions & 412 deletions compiler/rustc_resolve/src/late/lifetimes.rs

Large diffs are not rendered by default.

3 changes: 1 addition & 2 deletions compiler/rustc_trait_selection/src/traits/object_safety.rs
Original file line number Diff line number Diff line change
@@ -439,8 +439,7 @@ fn virtual_call_violation_for_method<'tcx>(
return Some(MethodViolationCode::WhereClauseReferencesSelf);
}

let receiver_ty =
tcx.liberate_late_bound_regions(method.def_id, sig.map_bound(|sig| sig.inputs()[0]));
let receiver_ty = tcx.liberate_late_bound_regions(method.def_id, sig.input(0));

// Until `unsized_locals` is fully implemented, `self: Self` can't be dispatched on.
// However, this is already considered object-safe. We allow it as a special case here.
8 changes: 8 additions & 0 deletions compiler/rustc_typeck/src/check/coercion.rs
Original file line number Diff line number Diff line change
@@ -973,6 +973,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
};
if let (Some(a_sig), Some(b_sig)) = (a_sig, b_sig) {
// Intrinsics are not coercible to function pointers.
if a_sig.abi() == Abi::RustIntrinsic
|| a_sig.abi() == Abi::PlatformIntrinsic
|| b_sig.abi() == Abi::RustIntrinsic
|| b_sig.abi() == Abi::PlatformIntrinsic
{
return Err(TypeError::IntrinsicCast);
}
// The signature must match.
let a_sig = self.normalize_associated_types_in(new.span, a_sig);
let b_sig = self.normalize_associated_types_in(new.span, b_sig);
4 changes: 2 additions & 2 deletions library/std/src/env.rs
Original file line number Diff line number Diff line change
@@ -799,7 +799,7 @@ impl DoubleEndedIterator for Args {
#[stable(feature = "std_debug", since = "1.16.0")]
impl fmt::Debug for Args {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Args").field("inner", &self.inner.inner.inner_debug()).finish()
f.debug_struct("Args").field("inner", &self.inner.inner).finish()
}
}

@@ -840,7 +840,7 @@ impl DoubleEndedIterator for ArgsOs {
#[stable(feature = "std_debug", since = "1.16.0")]
impl fmt::Debug for ArgsOs {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("ArgsOs").field("inner", &self.inner.inner_debug()).finish()
f.debug_struct("ArgsOs").field("inner", &self.inner).finish()
}
}

7 changes: 4 additions & 3 deletions library/std/src/sys/hermit/args.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::ffi::OsString;
use crate::fmt;
use crate::marker::PhantomData;
use crate::vec;

@@ -22,9 +23,9 @@ pub struct Args {
_dont_send_or_sync_me: PhantomData<*mut ()>,
}

impl Args {
pub fn inner_debug(&self) -> &[OsString] {
self.iter.as_slice()
impl fmt::Debug for Args {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.iter.as_slice().fmt(f)
}
}

7 changes: 4 additions & 3 deletions library/std/src/sys/sgx/args.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use super::abi::usercalls::{alloc, raw::ByteBuffer};
use crate::ffi::OsString;
use crate::fmt;
use crate::slice;
use crate::sync::atomic::{AtomicUsize, Ordering};
use crate::sys::os_str::Buf;
@@ -31,9 +32,9 @@ pub fn args() -> Args {

pub struct Args(slice::Iter<'static, OsString>);

impl Args {
pub fn inner_debug(&self) -> &[OsString] {
self.0.as_slice()
impl fmt::Debug for Args {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.0.as_slice().fmt(f)
}
}

7 changes: 4 additions & 3 deletions library/std/src/sys/unix/args.rs
Original file line number Diff line number Diff line change
@@ -6,6 +6,7 @@
#![allow(dead_code)] // runtime init functions not used during testing

use crate::ffi::OsString;
use crate::fmt;
use crate::marker::PhantomData;
use crate::vec;

@@ -29,9 +30,9 @@ pub struct Args {
_dont_send_or_sync_me: PhantomData<*mut ()>,
}

impl Args {
pub fn inner_debug(&self) -> &[OsString] {
self.iter.as_slice()
impl fmt::Debug for Args {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.iter.as_slice().fmt(f)
}
}

2 changes: 1 addition & 1 deletion library/std/src/sys/unix/os.rs
Original file line number Diff line number Diff line change
@@ -21,8 +21,8 @@ use crate::slice;
use crate::str;
use crate::sys::cvt;
use crate::sys::fd;
use crate::sys::rwlock::{RWLockReadGuard, StaticRWLock};
use crate::sys_common::mutex::{StaticMutex, StaticMutexGuard};
use crate::sys_common::rwlock::{RWLockReadGuard, StaticRWLock};
use crate::vec;

use libc::{c_char, c_int, c_void};
52 changes: 52 additions & 0 deletions library/std/src/sys/unix/rwlock.rs
Original file line number Diff line number Diff line change
@@ -139,3 +139,55 @@ impl RWLock {
}
}
}

pub struct StaticRWLock(RWLock);

impl StaticRWLock {
pub const fn new() -> StaticRWLock {
StaticRWLock(RWLock::new())
}

/// Acquires shared access to the underlying lock, blocking the current
/// thread to do so.
///
/// The lock is automatically unlocked when the returned guard is dropped.
#[inline]
pub fn read_with_guard(&'static self) -> RWLockReadGuard {
// SAFETY: All methods require static references, therefore self
// cannot be moved between invocations.
unsafe {
self.0.read();
}
RWLockReadGuard(&self.0)
}

/// Acquires write access to the underlying lock, blocking the current thread
/// to do so.
///
/// The lock is automatically unlocked when the returned guard is dropped.
#[inline]
pub fn write_with_guard(&'static self) -> RWLockWriteGuard {
// SAFETY: All methods require static references, therefore self
// cannot be moved between invocations.
unsafe {
self.0.write();
}
RWLockWriteGuard(&self.0)
}
}

pub struct RWLockReadGuard(&'static RWLock);

impl Drop for RWLockReadGuard {
fn drop(&mut self) {
unsafe { self.0.read_unlock() }
}
}

pub struct RWLockWriteGuard(&'static RWLock);

impl Drop for RWLockWriteGuard {
fn drop(&mut self) {
unsafe { self.0.write_unlock() }
}
}
6 changes: 3 additions & 3 deletions library/std/src/sys/unsupported/args.rs
Original file line number Diff line number Diff line change
@@ -9,9 +9,9 @@ pub fn args() -> Args {
Args {}
}

impl Args {
pub fn inner_debug(&self) -> &[OsString] {
&[]
impl fmt::Debug for Args {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_list().finish()
}
}

7 changes: 4 additions & 3 deletions library/std/src/sys/wasi/args.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#![deny(unsafe_op_in_unsafe_fn)]

use crate::ffi::{CStr, OsStr, OsString};
use crate::fmt;
use crate::marker::PhantomData;
use crate::os::wasi::ffi::OsStrExt;
use crate::vec;
@@ -38,9 +39,9 @@ fn maybe_args() -> Option<Vec<OsString>> {
}
}

impl Args {
pub fn inner_debug(&self) -> &[OsString] {
self.iter.as_slice()
impl fmt::Debug for Args {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.iter.as_slice().fmt(f)
}
}

7 changes: 4 additions & 3 deletions library/std/src/sys/wasm/args.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::ffi::OsString;
use crate::fmt;
use crate::marker::PhantomData;
use crate::vec;

@@ -17,9 +18,9 @@ pub struct Args {
_dont_send_or_sync_me: PhantomData<*mut ()>,
}

impl Args {
pub fn inner_debug(&self) -> &[OsString] {
self.iter.as_slice()
impl fmt::Debug for Args {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.iter.as_slice().fmt(f)
}
}

14 changes: 2 additions & 12 deletions library/std/src/sys/windows/args.rs
Original file line number Diff line number Diff line change
@@ -164,19 +164,9 @@ pub struct Args {
parsed_args_list: vec::IntoIter<OsString>,
}

pub struct ArgsInnerDebug<'a> {
args: &'a Args,
}

impl<'a> fmt::Debug for ArgsInnerDebug<'a> {
impl fmt::Debug for Args {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.args.parsed_args_list.as_slice().fmt(f)
}
}

impl Args {
pub fn inner_debug(&self) -> ArgsInnerDebug<'_> {
ArgsInnerDebug { args: self }
self.parsed_args_list.as_slice().fmt(f)
}
}

59 changes: 0 additions & 59 deletions library/std/src/sys_common/rwlock.rs
Original file line number Diff line number Diff line change
@@ -86,62 +86,3 @@ impl RWLock {
self.0.destroy()
}
}

// the cfg annotations only exist due to dead code warnings. the code itself is portable
#[cfg(unix)]
pub struct StaticRWLock(RWLock);

#[cfg(unix)]
impl StaticRWLock {
pub const fn new() -> StaticRWLock {
StaticRWLock(RWLock::new())
}

/// Acquires shared access to the underlying lock, blocking the current
/// thread to do so.
///
/// The lock is automatically unlocked when the returned guard is dropped.
#[inline]
pub fn read_with_guard(&'static self) -> RWLockReadGuard {
// SAFETY: All methods require static references, therefore self
// cannot be moved between invocations.
unsafe {
self.0.read();
}
RWLockReadGuard(&self.0)
}

/// Acquires write access to the underlying lock, blocking the current thread
/// to do so.
///
/// The lock is automatically unlocked when the returned guard is dropped.
#[inline]
pub fn write_with_guard(&'static self) -> RWLockWriteGuard {
// SAFETY: All methods require static references, therefore self
// cannot be moved between invocations.
unsafe {
self.0.write();
}
RWLockWriteGuard(&self.0)
}
}

#[cfg(unix)]
pub struct RWLockReadGuard(&'static RWLock);

#[cfg(unix)]
impl Drop for RWLockReadGuard {
fn drop(&mut self) {
unsafe { self.0.read_unlock() }
}
}

#[cfg(unix)]
pub struct RWLockWriteGuard(&'static RWLock);

#[cfg(unix)]
impl Drop for RWLockWriteGuard {
fn drop(&mut self) {
unsafe { self.0.write_unlock() }
}
}
13 changes: 9 additions & 4 deletions src/librustdoc/html/static/rustdoc.css
Original file line number Diff line number Diff line change
@@ -116,6 +116,8 @@ h4:not(.method):not(.type):not(.tymethod):not(.associatedconstant) {
padding-bottom: 6px;
}
h1.fqn {
display: flex;
width: 100%;
border-bottom: 1px dashed;
margin-top: 0;
}
@@ -458,6 +460,13 @@ nav.sub {
font-weight: normal;
}

h1.fqn > .out-of-band {
float: unset;
flex: 1;
text-align: right;
margin-left: 8px;
}

h3.impl > .out-of-band {
font-size: 21px;
}
@@ -1450,10 +1459,6 @@ h4 > .notable-traits {
padding: 0;
}

.content .in-band {
width: 100%;
}

.content h4 > .out-of-band {
position: inherit;
}
8 changes: 8 additions & 0 deletions src/test/ui/reify-intrinsic.rs
Original file line number Diff line number Diff line change
@@ -12,4 +12,12 @@ fn b() {
//~^ ERROR casting
}

fn c() {
let _ = [
std::intrinsics::copy_nonoverlapping::<i32>,
std::intrinsics::copy::<i32>,
//~^ ERROR cannot coerce
];
}

fn main() {}
11 changes: 10 additions & 1 deletion src/test/ui/reify-intrinsic.stderr
Original file line number Diff line number Diff line change
@@ -19,7 +19,16 @@ error[E0606]: casting `unsafe extern "rust-intrinsic" fn(_) -> _ {transmute::<_,
LL | let _ = std::mem::transmute as unsafe extern "rust-intrinsic" fn(isize) -> usize;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to 2 previous errors
error[E0308]: cannot coerce intrinsics to function pointers
--> $DIR/reify-intrinsic.rs:18:9
|
LL | std::intrinsics::copy::<i32>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot coerce intrinsics to function pointers
|
= note: expected type `unsafe extern "rust-intrinsic" fn(_, _, _) {copy_nonoverlapping::<i32>}`
found fn item `unsafe extern "rust-intrinsic" fn(_, _, _) {std::intrinsics::copy::<i32>}`

error: aborting due to 3 previous errors

Some errors have detailed explanations: E0308, E0606.
For more information about an error, try `rustc --explain E0308`.