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 7 pull requests #81832

Merged
merged 17 commits into from
Feb 6, 2021
Merged
Changes from all commits
Commits
Show all changes
17 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
49 changes: 49 additions & 0 deletions compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
@@ -2058,6 +2058,28 @@ pub enum PrimTy {
}

impl PrimTy {
/// All of the primitive types
pub const ALL: [Self; 17] = [
// any changes here should also be reflected in `PrimTy::from_name`
Self::Int(IntTy::I8),
Self::Int(IntTy::I16),
Self::Int(IntTy::I32),
Self::Int(IntTy::I64),
Self::Int(IntTy::I128),
Self::Int(IntTy::Isize),
Self::Uint(UintTy::U8),
Self::Uint(UintTy::U16),
Self::Uint(UintTy::U32),
Self::Uint(UintTy::U64),
Self::Uint(UintTy::U128),
Self::Uint(UintTy::Usize),
Self::Float(FloatTy::F32),
Self::Float(FloatTy::F64),
Self::Bool,
Self::Char,
Self::Str,
];

pub fn name_str(self) -> &'static str {
match self {
PrimTy::Int(i) => i.name_str(),
@@ -2079,6 +2101,33 @@ impl PrimTy {
PrimTy::Char => sym::char,
}
}

/// Returns the matching `PrimTy` for a `Symbol` such as "str" or "i32".
/// Returns `None` if no matching type is found.
pub fn from_name(name: Symbol) -> Option<Self> {
let ty = match name {
// any changes here should also be reflected in `PrimTy::ALL`
sym::i8 => Self::Int(IntTy::I8),
sym::i16 => Self::Int(IntTy::I16),
sym::i32 => Self::Int(IntTy::I32),
sym::i64 => Self::Int(IntTy::I64),
sym::i128 => Self::Int(IntTy::I128),
sym::isize => Self::Int(IntTy::Isize),
sym::u8 => Self::Uint(UintTy::U8),
sym::u16 => Self::Uint(UintTy::U16),
sym::u32 => Self::Uint(UintTy::U32),
sym::u64 => Self::Uint(UintTy::U64),
sym::u128 => Self::Uint(UintTy::U128),
sym::usize => Self::Uint(UintTy::Usize),
sym::f32 => Self::Float(FloatTy::F32),
sym::f64 => Self::Float(FloatTy::F64),
sym::bool => Self::Bool,
sym::char => Self::Char,
sym::str => Self::Str,
_ => return None,
};
Some(ty)
}
}

#[derive(Debug, HashStable_Generic)]
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

Lexical Region Resolution was removed in https://github.com/rust-lang/rust/pull/64790.

Rust now uses Non-lexical lifetimes. For more info, please see the [borrowck
6 changes: 3 additions & 3 deletions compiler/rustc_resolve/src/diagnostics.rs
Original file line number Diff line number Diff line change
@@ -9,6 +9,7 @@ use rustc_feature::BUILTIN_ATTRIBUTES;
use rustc_hir::def::Namespace::{self, *};
use rustc_hir::def::{self, CtorKind, CtorOf, DefKind, NonMacroAttrKind};
use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
use rustc_hir::PrimTy;
use rustc_middle::bug;
use rustc_middle::ty::{self, DefIdTree};
use rustc_session::Session;
@@ -718,10 +719,9 @@ impl<'a> Resolver<'a> {
}
}
Scope::BuiltinTypes => {
let primitive_types = &this.primitive_type_table.primitive_types;
suggestions.extend(primitive_types.iter().flat_map(|(name, prim_ty)| {
suggestions.extend(PrimTy::ALL.iter().filter_map(|prim_ty| {
let res = Res::PrimTy(*prim_ty);
filter_fn(res).then_some(TypoSuggestion::from_res(*name, res))
filter_fn(res).then_some(TypoSuggestion::from_res(prim_ty.name(), res))
}))
}
}
12 changes: 4 additions & 8 deletions compiler/rustc_resolve/src/late.rs
Original file line number Diff line number Diff line change
@@ -20,7 +20,7 @@ use rustc_errors::DiagnosticId;
use rustc_hir::def::Namespace::{self, *};
use rustc_hir::def::{self, CtorKind, DefKind, PartialRes, PerNS};
use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX};
use rustc_hir::TraitCandidate;
use rustc_hir::{PrimTy, TraitCandidate};
use rustc_middle::{bug, span_bug};
use rustc_session::lint;
use rustc_span::symbol::{kw, sym, Ident, Symbol};
@@ -1927,7 +1927,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
self.r.trait_map.insert(id, traits);
}

if self.r.primitive_type_table.primitive_types.contains_key(&path[0].ident.name) {
if PrimTy::from_name(path[0].ident.name).is_some() {
let mut std_path = Vec::with_capacity(1 + path.len());

std_path.push(Segment::from_ident(Ident::with_dummy_span(sym::std)));
@@ -2121,13 +2121,9 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
// The same fallback is used when `a` resolves to nothing.
PathResult::Module(ModuleOrUniformRoot::Module(_)) | PathResult::Failed { .. }
if (ns == TypeNS || path.len() > 1)
&& self
.r
.primitive_type_table
.primitive_types
.contains_key(&path[0].ident.name) =>
&& PrimTy::from_name(path[0].ident.name).is_some() =>
{
let prim = self.r.primitive_type_table.primitive_types[&path[0].ident.name];
let prim = PrimTy::from_name(path[0].ident.name).unwrap();
PartialRes::with_unresolved_segments(Res::PrimTy(prim), path.len() - 1)
}
PathResult::Module(ModuleOrUniformRoot::Module(module)) => {
4 changes: 2 additions & 2 deletions compiler/rustc_resolve/src/late/diagnostics.rs
Original file line number Diff line number Diff line change
@@ -1212,8 +1212,8 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
// Add primitive types to the mix
if filter_fn(Res::PrimTy(PrimTy::Bool)) {
names.extend(
self.r.primitive_type_table.primitive_types.iter().map(|(name, prim_ty)| {
TypoSuggestion::from_res(*name, Res::PrimTy(*prim_ty))
PrimTy::ALL.iter().map(|prim_ty| {
TypoSuggestion::from_res(prim_ty.name(), Res::PrimTy(*prim_ty))
}),
)
}
47 changes: 4 additions & 43 deletions compiler/rustc_resolve/src/lib.rs
Original file line number Diff line number Diff line change
@@ -25,7 +25,7 @@ use rustc_arena::{DroplessArena, TypedArena};
use rustc_ast::node_id::NodeMap;
use rustc_ast::unwrap_or;
use rustc_ast::visit::{self, Visitor};
use rustc_ast::{self as ast, FloatTy, IntTy, NodeId, UintTy};
use rustc_ast::{self as ast, NodeId};
use rustc_ast::{Crate, CRATE_NODE_ID};
use rustc_ast::{ItemKind, Path};
use rustc_ast_lowering::ResolverAstLowering;
@@ -39,8 +39,7 @@ use rustc_hir::def::Namespace::*;
use rustc_hir::def::{self, CtorOf, DefKind, NonMacroAttrKind, PartialRes};
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, CRATE_DEF_INDEX};
use rustc_hir::definitions::{DefKey, DefPathData, Definitions};
use rustc_hir::PrimTy::{self, Bool, Char, Float, Int, Str, Uint};
use rustc_hir::TraitCandidate;
use rustc_hir::{PrimTy, TraitCandidate};
use rustc_index::vec::IndexVec;
use rustc_metadata::creader::{CStore, CrateLoader};
use rustc_middle::hir::exports::ExportMap;
@@ -834,39 +833,6 @@ impl<'a> NameBinding<'a> {
}
}

/// Interns the names of the primitive types.
///
/// All other types are defined somewhere and possibly imported, but the primitive ones need
/// special handling, since they have no place of origin.
struct PrimitiveTypeTable {
primitive_types: FxHashMap<Symbol, PrimTy>,
}

impl PrimitiveTypeTable {
fn new() -> PrimitiveTypeTable {
let mut table = FxHashMap::default();

table.insert(sym::bool, Bool);
table.insert(sym::char, Char);
table.insert(sym::f32, Float(FloatTy::F32));
table.insert(sym::f64, Float(FloatTy::F64));
table.insert(sym::isize, Int(IntTy::Isize));
table.insert(sym::i8, Int(IntTy::I8));
table.insert(sym::i16, Int(IntTy::I16));
table.insert(sym::i32, Int(IntTy::I32));
table.insert(sym::i64, Int(IntTy::I64));
table.insert(sym::i128, Int(IntTy::I128));
table.insert(sym::str, Str);
table.insert(sym::usize, Uint(UintTy::Usize));
table.insert(sym::u8, Uint(UintTy::U8));
table.insert(sym::u16, Uint(UintTy::U16));
table.insert(sym::u32, Uint(UintTy::U32));
table.insert(sym::u64, Uint(UintTy::U64));
table.insert(sym::u128, Uint(UintTy::U128));
Self { primitive_types: table }
}
}

#[derive(Debug, Default, Clone)]
pub struct ExternPreludeEntry<'a> {
extern_crate_item: Option<&'a NameBinding<'a>>,
@@ -912,9 +878,6 @@ pub struct Resolver<'a> {
/// "self-confirming" import resolutions during import validation.
unusable_binding: Option<&'a NameBinding<'a>>,

/// The idents for the primitive types.
primitive_type_table: PrimitiveTypeTable,

/// Resolutions for nodes that have a single resolution.
partial_res_map: NodeMap<PartialRes>,
/// Resolutions for import nodes, which have multiple resolutions in different namespaces.
@@ -1284,8 +1247,6 @@ impl<'a> Resolver<'a> {
last_import_segment: false,
unusable_binding: None,

primitive_type_table: PrimitiveTypeTable::new(),

partial_res_map: Default::default(),
import_res_map: Default::default(),
label_res_map: Default::default(),
@@ -1994,9 +1955,9 @@ impl<'a> Resolver<'a> {
}

if ns == TypeNS {
if let Some(prim_ty) = self.primitive_type_table.primitive_types.get(&ident.name) {
if let Some(prim_ty) = PrimTy::from_name(ident.name) {
let binding =
(Res::PrimTy(*prim_ty), ty::Visibility::Public, DUMMY_SP, ExpnId::root())
(Res::PrimTy(prim_ty), ty::Visibility::Public, DUMMY_SP, ExpnId::root())
.to_name_binding(self.arenas);
return Some(LexicalScopeBinding::Item(binding));
}
11 changes: 5 additions & 6 deletions compiler/rustc_resolve/src/macros.rs
Original file line number Diff line number Diff line change
@@ -21,6 +21,7 @@ use rustc_expand::expand::{AstFragment, Invocation, InvocationKind};
use rustc_feature::is_builtin_attr_name;
use rustc_hir::def::{self, DefKind, NonMacroAttrKind};
use rustc_hir::def_id;
use rustc_hir::PrimTy;
use rustc_middle::middle::stability;
use rustc_middle::ty;
use rustc_session::lint::builtin::{SOFT_UNSTABLE, UNUSED_MACROS};
@@ -796,12 +797,10 @@ impl<'a> Resolver<'a> {
}
result
}
Scope::BuiltinTypes => {
match this.primitive_type_table.primitive_types.get(&ident.name).cloned() {
Some(prim_ty) => ok(Res::PrimTy(prim_ty), DUMMY_SP, this.arenas),
None => Err(Determinacy::Determined),
}
}
Scope::BuiltinTypes => match PrimTy::from_name(ident.name) {
Some(prim_ty) => ok(Res::PrimTy(prim_ty), DUMMY_SP, this.arenas),
None => Err(Determinacy::Determined),
},
};

match result {
Original file line number Diff line number Diff line change
@@ -117,7 +117,7 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
{
err.span_help(
tcx.def_span(def.did),
&format!("try adding a `where` bound using this expression: where [u8; {}]: Sized", snippet),
&format!("try adding a `where` bound using this expression: `where [u8; {}]: Sized`", snippet),
);
} else {
err.span_help(
Original file line number Diff line number Diff line change
@@ -1780,7 +1780,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
multispan.push_span_label(
sp,
format!(
"...if indirection was used here: `Box<{}>`",
"...if indirection were used here: `Box<{}>`",
param.name.ident(),
),
);
Original file line number Diff line number Diff line change
@@ -1103,7 +1103,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
// This is currently not possible to trigger because E0038 takes precedence, but
// leave it in for completeness in case anything changes in an earlier stage.
err.note(&format!(
"if trait `{}` was object safe, you could return a trait object",
"if trait `{}` were object-safe, you could return a trait object",
trait_obj,
));
}
23 changes: 14 additions & 9 deletions compiler/rustc_typeck/src/check/expr.rs
Original file line number Diff line number Diff line change
@@ -1460,28 +1460,33 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
),
);
err.span_label(field.ident.span, "field does not exist");
err.span_label(
err.span_suggestion(
ty_span,
&format!(
"`{adt}::{variant}` is a tuple {kind_name}, use the appropriate syntax",
adt = ty,
variant = variant.ident,
),
format!(
"`{adt}::{variant}` is a tuple {kind_name}, \
use the appropriate syntax: `{adt}::{variant}(/* fields */)`",
"{adt}::{variant}(/* fields */)",
adt = ty,
variant = variant.ident,
kind_name = kind_name
),
Applicability::HasPlaceholders,
);
}
_ => {
err.span_label(variant.ident.span, format!("`{adt}` defined here", adt = ty));
err.span_label(field.ident.span, "field does not exist");
err.span_label(
err.span_suggestion(
ty_span,
format!(
"`{adt}` is a tuple {kind_name}, \
use the appropriate syntax: `{adt}(/* fields */)`",
&format!(
"`{adt}` is a tuple {kind_name}, use the appropriate syntax",
adt = ty,
kind_name = kind_name
kind_name = kind_name,
),
format!("{adt}(/* fields */)", adt = ty),
Applicability::HasPlaceholders,
);
}
},
2 changes: 1 addition & 1 deletion compiler/rustc_typeck/src/check/mod.rs
Original file line number Diff line number Diff line change
@@ -838,7 +838,7 @@ fn missing_items_err(
// Obtain the level of indentation ending in `sugg_sp`.
let indentation = tcx.sess.source_map().span_to_margin(sugg_sp).unwrap_or(0);
// Make the whitespace that will make the suggestion have the right indentation.
let padding: String = (0..indentation).map(|_| " ").collect();
let padding: String = std::iter::repeat(" ").take(indentation).collect();

for trait_item in missing_items {
let snippet = suggestion_signature(&trait_item, tcx);
32 changes: 17 additions & 15 deletions library/alloc/src/collections/btree/map.rs
Original file line number Diff line number Diff line change
@@ -1151,21 +1151,23 @@ impl<K, V> BTreeMap<K, V> {
right
}

/// Creates an iterator which uses a closure to determine if an element should be removed.
///
/// If the closure returns true, the element is removed from the map and yielded.
/// If the closure returns false, or panics, the element remains in the map and will not be
/// yielded.
///
/// Note that `drain_filter` lets you mutate every value in the filter closure, regardless of
/// whether you choose to keep or remove it.
///
/// If the iterator is only partially consumed or not consumed at all, each of the remaining
/// elements will still be subjected to the closure and removed and dropped if it returns true.
///
/// It is unspecified how many more elements will be subjected to the closure
/// if a panic occurs in the closure, or a panic occurs while dropping an element,
/// or if the `DrainFilter` value is leaked.
/// Creates an iterator that visits all elements (key-value pairs) in
/// ascending key order and uses a closure to determine if an element should
/// be removed. If the closure returns `true`, the element is removed from
/// the map and yielded. If the closure returns `false`, or panics, the
/// element remains in the map and will not be yielded.
///
/// The iterator also lets you mutate the value of each element in the
/// closure, regardless of whether you choose to keep or remove it.
///
/// If the iterator is only partially consumed or not consumed at all, each
/// of the remaining elements is still subjected to the closure, which may
/// change its value and, by returning `true`, have the element removed and
/// dropped.
///
/// It is unspecified how many more elements will be subjected to the
/// closure if a panic occurs in the closure, or a panic occurs while
/// dropping an element, or if the `DrainFilter` value is leaked.
///
/// # Examples
///
2 changes: 1 addition & 1 deletion library/alloc/src/collections/btree/set.rs
Original file line number Diff line number Diff line change
@@ -679,7 +679,7 @@ impl<T> BTreeSet<T> {
/// use std::collections::BTreeSet;
///
/// let mut map = BTreeSet::new();
/// assert_eq!(map.first(), None);
/// assert_eq!(map.last(), None);
/// map.insert(1);
/// assert_eq!(map.last(), Some(&1));
/// map.insert(2);
2 changes: 1 addition & 1 deletion src/doc/rustc/src/exploit-mitigations.md
Original file line number Diff line number Diff line change
@@ -378,7 +378,7 @@ C library default allocator<sup id="fnref:5" role="doc-noteref"><a
href="#fn:5" class="footnote">5</a></sup> since version 1.32.0
(2019-01-17)[39].

```ignore
```rust,no_run
fn main() {
let mut x = Box::new([0; 1024]);

Loading