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 8 pull requests #84564

Merged
merged 34 commits into from
Apr 26, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
756be4a
refactored StyledBuffer parts into StyledChar
klensy Apr 16, 2021
f522991
added default for StyledChar
klensy Apr 16, 2021
e97dded
added some docs for StyledBuffer
klensy Apr 16, 2021
7e9d3c6
StyledBuffer::prepend: if line is empty, insert content without inser…
klensy Apr 16, 2021
247d74f
StyledBuffer::set_style: check overwrite first
klensy Apr 16, 2021
cb2d522
rename StyledBuffer.text to lines
klensy Apr 16, 2021
e4ce655
Handle pretty printing of `else if let` clauses
syvb Apr 23, 2021
fc97ce6
add tests for new behavior
syvb Apr 23, 2021
8629017
Add regression test
estebank Apr 24, 2021
64ee9cc
Recover trait import suggestion
estebank Apr 24, 2021
fb1fb7d
Tweak suggestion output
estebank Apr 24, 2021
ad78b50
Implemented suggestion.
Apr 24, 2021
0e7489a
Added a test.
Apr 24, 2021
8bc81a0
Refactor.
Apr 24, 2021
05a5a11
More tests.
Apr 24, 2021
8ebd811
review
klensy Apr 17, 2021
3b50461
One more test case.
Apr 24, 2021
fbc2aad
Inline most raw socket, fd and handle conversions
Apr 25, 2021
e558ddb
Improve diagnostics for function passed when a type was expected.
hameerabbasi Apr 24, 2021
9082078
unsafety checking: no longer care about is_min_const_fn
RalfJung Apr 25, 2021
1ecdaa2
remove now-unused 'is_min_const_fn'
RalfJung Apr 25, 2021
43126f3
get rid of min_const_fn references in library/ and rustdoc
RalfJung Apr 25, 2021
b1ad1fb
make sure raw ptr casts in 'const' context are unsafe
RalfJung Apr 25, 2021
421d54e
fix clippy
RalfJung Apr 25, 2021
588530d
fix typography
RalfJung Apr 25, 2021
d326a4b
Give a better error when std or core are missing
jyn514 Apr 22, 2021
e7e22b4
Rollup merge of #84235 - klensy:styled-buffer, r=lcnr
Dylan-DPC Apr 25, 2021
379a55c
Rollup merge of #84450 - jyn514:missing-std, r=petrochenkov
Dylan-DPC Apr 25, 2021
a0dcbdf
Rollup merge of #84486 - Smittyvb:else-if-let-hir-pretty-print, r=pet…
Dylan-DPC Apr 25, 2021
ae316d6
Rollup merge of #84499 - estebank:issue-84272, r=jackh726
Dylan-DPC Apr 25, 2021
ad3389a
Rollup merge of #84516 - torhovland:issue-84114, r=estebank
Dylan-DPC Apr 25, 2021
1397499
Rollup merge of #84520 - hameerabbasi:fn-as-ty, r=lcnr
Dylan-DPC Apr 25, 2021
25508eb
Rollup merge of #84541 - KaiJewson:inline-raw, r=m-ou-se
Dylan-DPC Apr 25, 2021
000a630
Rollup merge of #84547 - RalfJung:max_const_fn, r=oli-obk
Dylan-DPC Apr 25, 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
90 changes: 55 additions & 35 deletions compiler/rustc_errors/src/styled_buffer.rs
Original file line number Diff line number Diff line change
@@ -1,39 +1,52 @@
// Code for creating styled buffers

use crate::snippet::{Style, StyledString};
use std::iter;

#[derive(Debug)]
pub struct StyledBuffer {
text: Vec<Vec<char>>,
styles: Vec<Vec<Style>>,
lines: Vec<Vec<StyledChar>>,
}

#[derive(Debug, Clone)]
struct StyledChar {
chr: char,
style: Style,
}

impl StyledChar {
const SPACE: Self = StyledChar::new(' ', Style::NoStyle);

const fn new(chr: char, style: Style) -> Self {
StyledChar { chr, style }
}
}

impl StyledBuffer {
pub fn new() -> StyledBuffer {
StyledBuffer { text: vec![], styles: vec![] }
StyledBuffer { lines: vec![] }
}

/// Returns content of `StyledBuffer` splitted by lines and line styles
pub fn render(&self) -> Vec<Vec<StyledString>> {
// Tabs are assumed to have been replaced by spaces in calling code.
debug_assert!(self.text.iter().all(|r| !r.contains(&'\t')));
debug_assert!(self.lines.iter().all(|r| !r.iter().any(|sc| sc.chr == '\t')));

let mut output: Vec<Vec<StyledString>> = vec![];
let mut styled_vec: Vec<StyledString> = vec![];

for (row, row_style) in iter::zip(&self.text, &self.styles) {
for styled_line in &self.lines {
let mut current_style = Style::NoStyle;
let mut current_text = String::new();

for (&c, &s) in iter::zip(row, row_style) {
if s != current_style {
for sc in styled_line {
if sc.style != current_style {
if !current_text.is_empty() {
styled_vec.push(StyledString { text: current_text, style: current_style });
}
current_style = s;
current_style = sc.style;
current_text = String::new();
}
current_text.push(c);
current_text.push(sc.chr);
}
if !current_text.is_empty() {
styled_vec.push(StyledString { text: current_text, style: current_style });
Expand All @@ -49,29 +62,25 @@ impl StyledBuffer {
}

fn ensure_lines(&mut self, line: usize) {
while line >= self.text.len() {
self.text.push(vec![]);
self.styles.push(vec![]);
if line >= self.lines.len() {
self.lines.resize(line + 1, Vec::new());
}
}

/// Sets `chr` with `style` for given `line`, `col`.
/// If `line` does not exist in our buffer, adds empty lines up to the given
/// and fills the last line with unstyled whitespace.
pub fn putc(&mut self, line: usize, col: usize, chr: char, style: Style) {
self.ensure_lines(line);
if col < self.text[line].len() {
self.text[line][col] = chr;
self.styles[line][col] = style;
} else {
let mut i = self.text[line].len();
while i < col {
self.text[line].push(' ');
self.styles[line].push(Style::NoStyle);
i += 1;
}
self.text[line].push(chr);
self.styles[line].push(style);
if col >= self.lines[line].len() {
self.lines[line].resize(col + 1, StyledChar::SPACE);
}
self.lines[line][col] = StyledChar::new(chr, style);
}

/// Sets `string` with `style` for given `line`, starting from `col`.
/// If `line` does not exist in our buffer, adds empty lines up to the given
/// and fills the last line with unstyled whitespace.
pub fn puts(&mut self, line: usize, col: usize, string: &str, style: Style) {
let mut n = col;
for c in string.chars() {
Expand All @@ -80,32 +89,40 @@ impl StyledBuffer {
}
}

/// For given `line` inserts `string` with `style` before old content of that line,
/// adding lines if needed
pub fn prepend(&mut self, line: usize, string: &str, style: Style) {
self.ensure_lines(line);
let string_len = string.chars().count();

// Push the old content over to make room for new content
for _ in 0..string_len {
self.styles[line].insert(0, Style::NoStyle);
self.text[line].insert(0, ' ');
if !self.lines[line].is_empty() {
// Push the old content over to make room for new content
for _ in 0..string_len {
self.lines[line].insert(0, StyledChar::SPACE);
}
}

self.puts(line, 0, string, style);
}

/// For given `line` inserts `string` with `style` after old content of that line,
/// adding lines if needed
pub fn append(&mut self, line: usize, string: &str, style: Style) {
if line >= self.text.len() {
if line >= self.lines.len() {
self.puts(line, 0, string, style);
} else {
let col = self.text[line].len();
let col = self.lines[line].len();
self.puts(line, col, string, style);
}
}

pub fn num_lines(&self) -> usize {
self.text.len()
self.lines.len()
}

/// Set `style` for `line`, `col_start..col_end` range if:
/// 1. That line and column range exist in `StyledBuffer`
/// 2. `overwrite` is `true` or existing style is `Style::NoStyle` or `Style::Quotation`
pub fn set_style_range(
&mut self,
line: usize,
Expand All @@ -119,10 +136,13 @@ impl StyledBuffer {
}
}

/// Set `style` for `line`, `col` if:
/// 1. That line and column exist in `StyledBuffer`
/// 2. `overwrite` is `true` or existing style is `Style::NoStyle` or `Style::Quotation`
pub fn set_style(&mut self, line: usize, col: usize, style: Style, overwrite: bool) {
if let Some(ref mut line) = self.styles.get_mut(line) {
if let Some(s) = line.get_mut(col) {
if *s == Style::NoStyle || *s == Style::Quotation || overwrite {
if let Some(ref mut line) = self.lines.get_mut(line) {
if let Some(StyledChar { style: s, .. }) = line.get_mut(col) {
if overwrite || *s == Style::NoStyle || *s == Style::Quotation {
*s = style;
}
}
Expand Down
24 changes: 22 additions & 2 deletions compiler/rustc_hir_pretty/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1095,8 +1095,8 @@ impl<'a> State<'a> {

fn print_else(&mut self, els: Option<&hir::Expr<'_>>) {
match els {
Some(_else) => {
match _else.kind {
Some(else_) => {
match else_.kind {
// "another else-if"
hir::ExprKind::If(ref i, ref then, ref e) => {
self.cbox(INDENT_UNIT - 1);
Expand All @@ -1114,6 +1114,26 @@ impl<'a> State<'a> {
self.s.word(" else ");
self.print_block(&b)
}
hir::ExprKind::Match(ref expr, arms, _) => {
// else if let desugared to match
assert!(arms.len() == 2, "if let desugars to match with two arms");

self.s.word(" else ");
self.s.word("{");

self.cbox(INDENT_UNIT);
self.ibox(INDENT_UNIT);
self.word_nbsp("match");
self.print_expr_as_cond(&expr);
self.s.space();
self.bopen();
for arm in arms {
self.print_arm(arm);
}
self.bclose(expr.span);

self.s.word("}");
}
// BLEAH, constraints would be great here
_ => {
panic!("print_if saw if with weird alternative");
Expand Down
7 changes: 5 additions & 2 deletions compiler/rustc_metadata/src/creader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -511,8 +511,11 @@ impl<'a> CrateLoader<'a> {
if dep.is_none() {
self.used_extern_options.insert(name);
}
self.maybe_resolve_crate(name, dep_kind, dep)
.unwrap_or_else(|err| err.report(self.sess, span))
self.maybe_resolve_crate(name, dep_kind, dep).unwrap_or_else(|err| {
let missing_core =
self.maybe_resolve_crate(sym::core, CrateDepKind::Explicit, None).is_err();
err.report(&self.sess, span, missing_core)
})
}

fn maybe_resolve_crate<'b>(
Expand Down
37 changes: 34 additions & 3 deletions compiler/rustc_metadata/src/locator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -790,7 +790,8 @@ pub fn find_plugin_registrar(
) -> (PathBuf, CrateDisambiguator) {
match find_plugin_registrar_impl(sess, metadata_loader, name) {
Ok(res) => res,
Err(err) => err.report(sess, span),
// `core` is always available if we got as far as loading plugins.
Err(err) => err.report(sess, span, false),
}
}

Expand Down Expand Up @@ -883,7 +884,7 @@ crate enum CrateError {
}

impl CrateError {
crate fn report(self, sess: &Session, span: Span) -> ! {
crate fn report(self, sess: &Session, span: Span, missing_core: bool) -> ! {
let mut err = match self {
CrateError::NonAsciiName(crate_name) => sess.struct_span_err(
span,
Expand Down Expand Up @@ -1068,7 +1069,37 @@ impl CrateError {
if (crate_name == sym::std || crate_name == sym::core)
&& locator.triple != TargetTriple::from_triple(config::host_triple())
{
err.note(&format!("the `{}` target may not be installed", locator.triple));
if missing_core {
err.note(&format!(
"the `{}` target may not be installed",
locator.triple
));
} else {
err.note(&format!(
"the `{}` target may not support the standard library",
locator.triple
));
}
if missing_core && std::env::var("RUSTUP_HOME").is_ok() {
err.help(&format!(
"consider downloading the target with `rustup target add {}`",
locator.triple
));
}
// Suggest using #![no_std]. #[no_core] is unstable and not really supported anyway.
// NOTE: this is a dummy span if `extern crate std` was injected by the compiler.
// If it's not a dummy, that means someone added `extern crate std` explicitly and `#![no_std]` won't help.
if !missing_core && span.is_dummy() {
let current_crate =
sess.opts.crate_name.as_deref().unwrap_or("<unknown>");
err.note(&format!(
"`std` is required by `{}` because it does not declare `#![no_std]`",
current_crate
));
}
if sess.is_nightly_build() && std::env::var("CARGO").is_ok() {
err.help("consider building the standard library from source with `cargo build -Zbuild-std`");
}
} else if crate_name == sym::profiler_builtins {
err.note(&"the compiler may have been built without the profiler runtime");
}
Expand Down
4 changes: 1 addition & 3 deletions compiler/rustc_middle/src/mir/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,8 @@ use super::{Field, SourceInfo};

#[derive(Copy, Clone, PartialEq, TyEncodable, TyDecodable, HashStable, Debug)]
pub enum UnsafetyViolationKind {
/// Only permitted in regular `fn`s, prohibited in `const fn`s.
/// Unsafe operation outside `unsafe`.
General,
/// Permitted both in `const fn`s and regular `fn`s.
GeneralAndConstFn,
/// Unsafe operation in an `unsafe fn` but outside an `unsafe` block.
/// Has to be handled as a lint for backwards compatibility.
UnsafeFn,
Expand Down
49 changes: 0 additions & 49 deletions compiler/rustc_mir/src/const_eval/fn_queries.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use rustc_attr as attr;
use rustc_hir as hir;
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_middle::hir::map::blocks::FnLikeNode;
Expand Down Expand Up @@ -34,54 +33,6 @@ pub fn is_unstable_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> Option<Symbol> {
}
}

/// Returns `true` if this function must conform to `min_const_fn`
pub fn is_min_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
// Bail out if the signature doesn't contain `const`
if !tcx.is_const_fn_raw(def_id) {
return false;
}

if tcx.features().staged_api {
// In order for a libstd function to be considered min_const_fn
// it needs to be stable and have no `rustc_const_unstable` attribute.
match tcx.lookup_const_stability(def_id) {
// `rustc_const_unstable` functions don't need to conform.
Some(&attr::ConstStability { ref level, .. }) if level.is_unstable() => false,
None => {
if let Some(stab) = tcx.lookup_stability(def_id) {
if stab.level.is_stable() {
tcx.sess.delay_span_bug(
tcx.def_span(def_id),
"stable const functions must have either `rustc_const_stable` or \
`rustc_const_unstable` attribute",
);
// While we errored above, because we don't know if we need to conform, we
// err on the "safe" side and require min_const_fn.
true
} else {
// Unstable functions need not conform to min_const_fn.
false
}
} else {
// Internal functions are forced to conform to min_const_fn.
// Annotate the internal function with a const stability attribute if
// you need to use unstable features.
// Note: this is an arbitrary choice that does not affect stability or const
// safety or anything, it just changes whether we need to annotate some
// internal functions with `rustc_const_stable` or with `rustc_const_unstable`
true
}
}
// Everything else needs to conform, because it would be callable from
// other `min_const_fn` functions.
_ => true,
}
} else {
// users enabling the `const_fn` feature gate can do what they want
!tcx.features().const_fn
}
}

pub fn is_parent_const_impl_raw(tcx: TyCtxt<'_>, hir_id: hir::HirId) -> bool {
let parent_id = tcx.hir().get_parent_did(hir_id);
if !parent_id.is_top_level_module() { is_const_impl_raw(tcx, parent_id) } else { false }
Expand Down
Loading