Skip to content

Rollup of 5 pull requests #71958

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

Merged
merged 28 commits into from
May 7, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
9e43b00
Turn of rustc-dev-guide toolstate for now
mark-i-m May 1, 2020
75f066d
Handle binop on unbound type param
estebank Apr 7, 2020
1473a66
Suggest restricting type param when it doesn't satisfy projection
estebank Apr 7, 2020
3453db7
review comments: use or-pattern
estebank Apr 7, 2020
d8d02f8
On incorrect equality constraint likely to be assoc type, suggest app…
estebank Apr 8, 2020
c93c660
review comments and rebase fix
estebank Apr 17, 2020
5d64e91
review comment: use `body_id`
estebank Apr 19, 2020
b13f234
fix rebase
estebank May 4, 2020
b17b20c
Add docstring to `deny_equality_constraints`
estebank May 4, 2020
ab7360d
refactor suggest_traits_to_import
lcnr May 4, 2020
e17f36b
Replace title "Methods" with "Implementations"
GuillaumeGomez May 5, 2020
cf18482
Update tests
GuillaumeGomez May 5, 2020
4ade6eb
Add test for new implementations section title
GuillaumeGomez May 5, 2020
758519c
Index IDs already used by rustdoc template
GuillaumeGomez May 5, 2020
e0320b5
validation: port more checks to the pattern-based macro (and give it …
RalfJung May 5, 2020
aa2eaca
add test for insufficiently aligned vtable
RalfJung May 5, 2020
837c16b
comment out rustc-dev-guide in NIGHTLY_TOOLS
mark-i-m May 6, 2020
19bd72e
convert remaining try_validation to new macro
RalfJung May 6, 2020
a64d643
Update librustdoc ID tests
GuillaumeGomez May 6, 2020
441419a
properly catch invalid-drop-fn errors
RalfJung May 6, 2020
7c44226
convert throw_validation_failure macro to same syntax as try_validation
RalfJung May 6, 2020
8998c7a
try_validation: handle multi-branching, and use macro for most remain…
RalfJung May 6, 2020
0e2a712
more precise vtable errors
RalfJung May 6, 2020
ce14d6d
Rollup merge of #70908 - estebank:suggest-add, r=nikomatsakis
Dylan-DPC May 6, 2020
7fc579f
Rollup merge of #71731 - mark-i-m:guide-toolstate-off-for-now, r=kennytm
Dylan-DPC May 6, 2020
f7c3b0c
Rollup merge of #71888 - lcnr:refactor-suggest_traits_to_import, r=es…
Dylan-DPC May 6, 2020
d33180e
Rollup merge of #71918 - GuillaumeGomez:rename-methods-section, r=Dyl…
Dylan-DPC May 6, 2020
066eb08
Rollup merge of #71950 - RalfJung:try-validation-cleanup, r=oli-obk
Dylan-DPC May 6, 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
2 changes: 1 addition & 1 deletion src/bootstrap/toolstate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ static STABLE_TOOLS: &[(&str, &str)] = &[
static NIGHTLY_TOOLS: &[(&str, &str)] = &[
("miri", "src/tools/miri"),
("embedded-book", "src/doc/embedded-book"),
("rustc-dev-guide", "src/doc/rustc-dev-guide"),
// ("rustc-dev-guide", "src/doc/rustc-dev-guide"),
];

fn print_error(tool: &str, submodule: &str) {
Expand Down
1 change: 0 additions & 1 deletion src/ci/docker/x86_64-gnu-tools/checktools.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ python3 "$X_PY" test --no-fail-fast \
src/doc/rust-by-example \
src/doc/embedded-book \
src/doc/edition-guide \
src/doc/rustc-dev-guide \
src/tools/clippy \
src/tools/rls \
src/tools/rustfmt \
Expand Down
96 changes: 85 additions & 11 deletions src/librustc_ast_passes/ast_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ use rustc_session::Session;
use rustc_span::symbol::{kw, sym};
use rustc_span::Span;
use std::mem;
use std::ops::DerefMut;

const MORE_EXTERN: &str =
"for more information, visit https://doc.rust-lang.org/std/keyword.extern.html";
Expand Down Expand Up @@ -1113,17 +1114,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {

for predicate in &generics.where_clause.predicates {
if let WherePredicate::EqPredicate(ref predicate) = *predicate {
self.err_handler()
.struct_span_err(
predicate.span,
"equality constraints are not yet supported in `where` clauses",
)
.span_label(predicate.span, "not supported")
.note(
"see issue #20041 <https://github.com/rust-lang/rust/issues/20041> \
for more information",
)
.emit();
deny_equality_constraints(self, predicate, generics);
}
}

Expand Down Expand Up @@ -1300,6 +1291,89 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
}
}

/// When encountering an equality constraint in a `where` clause, emit an error. If the code seems
/// like it's setting an associated type, provide an appropriate suggestion.
fn deny_equality_constraints(
this: &mut AstValidator<'_>,
predicate: &WhereEqPredicate,
generics: &Generics,
) {
let mut err = this.err_handler().struct_span_err(
predicate.span,
"equality constraints are not yet supported in `where` clauses",
);
err.span_label(predicate.span, "not supported");

// Given `<A as Foo>::Bar = RhsTy`, suggest `A: Foo<Bar = RhsTy>`.
if let TyKind::Path(Some(qself), full_path) = &predicate.lhs_ty.kind {
if let TyKind::Path(None, path) = &qself.ty.kind {
match &path.segments[..] {
[PathSegment { ident, args: None, .. }] => {
for param in &generics.params {
if param.ident == *ident {
let param = ident;
match &full_path.segments[qself.position..] {
[PathSegment { ident, .. }] => {
// Make a new `Path` from `foo::Bar` to `Foo<Bar = RhsTy>`.
let mut assoc_path = full_path.clone();
// Remove `Bar` from `Foo::Bar`.
assoc_path.segments.pop();
let len = assoc_path.segments.len() - 1;
// Build `<Bar = RhsTy>`.
let arg = AngleBracketedArg::Constraint(AssocTyConstraint {
id: rustc_ast::node_id::DUMMY_NODE_ID,
ident: *ident,
kind: AssocTyConstraintKind::Equality {
ty: predicate.rhs_ty.clone(),
},
span: ident.span,
});
// Add `<Bar = RhsTy>` to `Foo`.
match &mut assoc_path.segments[len].args {
Some(args) => match args.deref_mut() {
GenericArgs::Parenthesized(_) => continue,
GenericArgs::AngleBracketed(args) => {
args.args.push(arg);
}
},
empty_args => {
*empty_args = AngleBracketedArgs {
span: ident.span,
args: vec![arg],
}
.into();
}
}
err.span_suggestion_verbose(
predicate.span,
&format!(
"if `{}` is an associated type you're trying to set, \
use the associated type binding syntax",
ident
),
format!(
"{}: {}",
param,
pprust::path_to_string(&assoc_path)
),
Applicability::MaybeIncorrect,
);
}
_ => {}
};
}
}
}
_ => {}
}
}
}
err.note(
"see issue #20041 <https://github.com/rust-lang/rust/issues/20041> for more information",
);
err.emit();
}

pub fn check_crate(session: &Session, krate: &Crate, lints: &mut LintBuffer) -> bool {
let mut validator = AstValidator {
session,
Expand Down
36 changes: 35 additions & 1 deletion src/librustc_hir/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2626,8 +2626,42 @@ impl Node<'_> {
match self {
Node::TraitItem(TraitItem { generics, .. })
| Node::ImplItem(ImplItem { generics, .. })
| Node::Item(Item { kind: ItemKind::Fn(_, generics, _), .. }) => Some(generics),
| Node::Item(Item {
kind:
ItemKind::Trait(_, _, generics, ..)
| ItemKind::Impl { generics, .. }
| ItemKind::Fn(_, generics, _),
..
}) => Some(generics),
_ => None,
}
}

pub fn hir_id(&self) -> Option<HirId> {
match self {
Node::Item(Item { hir_id, .. })
| Node::ForeignItem(ForeignItem { hir_id, .. })
| Node::TraitItem(TraitItem { hir_id, .. })
| Node::ImplItem(ImplItem { hir_id, .. })
| Node::Field(StructField { hir_id, .. })
| Node::AnonConst(AnonConst { hir_id, .. })
| Node::Expr(Expr { hir_id, .. })
| Node::Stmt(Stmt { hir_id, .. })
| Node::Ty(Ty { hir_id, .. })
| Node::Binding(Pat { hir_id, .. })
| Node::Pat(Pat { hir_id, .. })
| Node::Arm(Arm { hir_id, .. })
| Node::Block(Block { hir_id, .. })
| Node::Local(Local { hir_id, .. })
| Node::MacroDef(MacroDef { hir_id, .. })
| Node::Lifetime(Lifetime { hir_id, .. })
| Node::Param(Param { hir_id, .. })
| Node::GenericParam(GenericParam { hir_id, .. }) => Some(*hir_id),
Node::TraitRef(TraitRef { hir_ref_id, .. }) => Some(*hir_ref_id),
Node::PathSegment(PathSegment { hir_id, .. }) => *hir_id,
Node::Variant(Variant { id, .. }) => Some(*id),
Node::Ctor(variant) => variant.ctor_hir_id(),
Node::Crate(_) | Node::Visibility(_) => None,
}
}
}
19 changes: 14 additions & 5 deletions src/librustc_middle/mir/interpret/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ use super::{AllocId, Pointer, RawConst, ScalarMaybeUndef};
use crate::mir::interpret::ConstValue;
use crate::ty::layout::LayoutError;
use crate::ty::query::TyCtxtAt;
use crate::ty::tls;
use crate::ty::{self, layout, Ty};
use crate::ty::{self, layout, tls, FnSig, Ty};

use rustc_data_structures::sync::Lock;
use rustc_errors::{struct_span_err, DiagnosticBuilder, ErrorReported};
Expand Down Expand Up @@ -329,7 +328,7 @@ impl fmt::Display for CheckInAllocMsg {
}

/// Error information for when the program caused Undefined Behavior.
pub enum UndefinedBehaviorInfo {
pub enum UndefinedBehaviorInfo<'tcx> {
/// Free-form case. Only for errors that are never caught!
Ub(String),
/// Unreachable code was executed.
Expand All @@ -347,6 +346,8 @@ pub enum UndefinedBehaviorInfo {
PointerArithOverflow,
/// Invalid metadata in a wide pointer (using `str` to avoid allocations).
InvalidMeta(&'static str),
/// Invalid drop function in vtable.
InvalidDropFn(FnSig<'tcx>),
/// Reading a C string that does not end within its allocation.
UnterminatedCString(Pointer),
/// Dereferencing a dangling pointer after it got freed.
Expand Down Expand Up @@ -380,6 +381,8 @@ pub enum UndefinedBehaviorInfo {
InvalidDiscriminant(ScalarMaybeUndef),
/// Using a pointer-not-to-a-function as function pointer.
InvalidFunctionPointer(Pointer),
/// Using a string that is not valid UTF-8,
InvalidStr(std::str::Utf8Error),
/// Using uninitialized data where it is not allowed.
InvalidUndefBytes(Option<Pointer>),
/// Working with a local that is not currently live.
Expand All @@ -391,7 +394,7 @@ pub enum UndefinedBehaviorInfo {
},
}

impl fmt::Display for UndefinedBehaviorInfo {
impl fmt::Display for UndefinedBehaviorInfo<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
use UndefinedBehaviorInfo::*;
match self {
Expand All @@ -404,6 +407,11 @@ impl fmt::Display for UndefinedBehaviorInfo {
RemainderByZero => write!(f, "calculating the remainder with a divisor of zero"),
PointerArithOverflow => write!(f, "overflowing in-bounds pointer arithmetic"),
InvalidMeta(msg) => write!(f, "invalid metadata in wide pointer: {}", msg),
InvalidDropFn(sig) => write!(
f,
"invalid drop function signature: got {}, expected exactly one argument which must be a pointer type",
sig
),
UnterminatedCString(p) => write!(
f,
"reading a null-terminated string starting at {} with no null found before end of allocation",
Expand Down Expand Up @@ -446,6 +454,7 @@ impl fmt::Display for UndefinedBehaviorInfo {
InvalidFunctionPointer(p) => {
write!(f, "using {} as function pointer but it does not point to a function", p)
}
InvalidStr(err) => write!(f, "this string is not valid UTF-8: {}", err),
InvalidUndefBytes(Some(p)) => write!(
f,
"reading uninitialized memory at {}, but this operation requires initialized memory",
Expand Down Expand Up @@ -549,7 +558,7 @@ impl dyn MachineStopType {

pub enum InterpError<'tcx> {
/// The program caused undefined behavior.
UndefinedBehavior(UndefinedBehaviorInfo),
UndefinedBehavior(UndefinedBehaviorInfo<'tcx>),
/// The program did something the interpreter does not support (some of these *might* be UB
/// but the interpreter is not sure).
Unsupported(UnsupportedOpInfo),
Expand Down
Loading