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 #108464

Merged
merged 21 commits into from
Feb 26, 2023
Merged
Changes from 1 commit
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
ee5404c
Add additional options to `x setup`
clubby789 Feb 9, 2023
960ac2e
[107049] Recognise top level keys in config.toml.example
lionellloh Feb 19, 2023
5643706
Removed trailing spaces to satisfy lint
lionellloh Feb 20, 2023
fc5db2c
Implement -Zlink-directives=yes/no
jsgf Feb 4, 2023
fde2e40
link-directives: clarify usage message
jsgf Feb 8, 2023
5965948
Remove a back compat warning
oli-obk Jan 25, 2023
e39fe37
Add check for invalid \`#[macro_export]\` arguments
blyxyas Feb 10, 2023
60b0da1
Test rustdoc encountering `proc_macro_derive` in a non-proc-macro crate
oli-obk Feb 9, 2023
98525ae
Check object's supertrait and associated type bounds in new solver
compiler-errors Feb 22, 2023
2540c2b
Make higher-ranked projections in object types work in new solver
compiler-errors Feb 22, 2023
ed30eff
Comments, another test
compiler-errors Feb 22, 2023
34813e2
Test that the compiler/library builds with -Zmir-opt-level=3 -Zvalida…
chenyukang Dec 15, 2022
15813cf
enable validate-mir-opts in mingw-check
chenyukang Dec 28, 2022
001bcee
check is default to all targets now
chenyukang Feb 24, 2023
b90a385
Rollup merge of #105736 - chenyukang:yukang/add-mir-opt-level-testing…
compiler-errors Feb 25, 2023
a4119ba
Rollup merge of #107291 - oli-obk:rustdoc_breaking_change, r=estebank
compiler-errors Feb 25, 2023
1a599d7
Rollup merge of #107675 - jsgf:link-directives, r=davidtwco
compiler-errors Feb 25, 2023
3905517
Rollup merge of #107848 - clubby789:x-setup-options, r=Mark-Simulacrum
compiler-errors Feb 25, 2023
cf049ac
Rollup merge of #107911 - blyxyas:issue-107231-fix, r=compiler-errors
compiler-errors Feb 25, 2023
0b6b373
Rollup merge of #108229 - lionellloh:issue-107049, r=Mark-Simulacrum
compiler-errors Feb 25, 2023
4723a9a
Rollup merge of #108333 - compiler-errors:new-solver-object-sound, r=…
compiler-errors Feb 25, 2023
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
Prev Previous commit
Next Next commit
Check object's supertrait and associated type bounds in new solver
compiler-errors committed Feb 24, 2023
commit 98525aeee7b1f0ddf3573c2921a0d1ef914774a8
11 changes: 10 additions & 1 deletion compiler/rustc_trait_selection/src/solve/assembly.rs
Original file line number Diff line number Diff line change
@@ -99,6 +99,15 @@ pub(super) trait GoalKind<'tcx>: TypeFoldable<TyCtxt<'tcx>> + Copy + Eq {
requirements: impl IntoIterator<Item = Goal<'tcx, ty::Predicate<'tcx>>>,
) -> QueryResult<'tcx>;

// Consider a clause specifically for a `dyn Trait` self type. This requires
// additionally checking all of the supertraits and object bounds to hold,
// since they're not implied by the well-formedness of the object type.
fn consider_object_bound_candidate(
ecx: &mut EvalCtxt<'_, 'tcx>,
goal: Goal<'tcx, Self>,
assumption: ty::Predicate<'tcx>,
) -> QueryResult<'tcx>;

fn consider_impl_candidate(
ecx: &mut EvalCtxt<'_, 'tcx>,
goal: Goal<'tcx, Self>,
@@ -455,7 +464,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
for assumption in
elaborate_predicates(tcx, bounds.iter().map(|bound| bound.with_self_ty(tcx, self_ty)))
{
match G::consider_implied_clause(self, goal, assumption.predicate, []) {
match G::consider_object_bound_candidate(self, goal, assumption.predicate) {
Ok(result) => {
candidates.push(Candidate { source: CandidateSource::BuiltinImpl, result })
}
44 changes: 44 additions & 0 deletions compiler/rustc_trait_selection/src/solve/project_goals.rs
Original file line number Diff line number Diff line change
@@ -128,6 +128,50 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
}
}

fn consider_object_bound_candidate(
ecx: &mut EvalCtxt<'_, 'tcx>,
goal: Goal<'tcx, Self>,
assumption: ty::Predicate<'tcx>,
) -> QueryResult<'tcx> {
if let Some(poly_projection_pred) = assumption.to_opt_poly_projection_pred()
&& poly_projection_pred.projection_def_id() == goal.predicate.def_id()
{
ecx.probe(|ecx| {
let assumption_projection_pred =
ecx.instantiate_binder_with_infer(poly_projection_pred);
let mut nested_goals = ecx.eq(
goal.param_env,
goal.predicate.projection_ty,
assumption_projection_pred.projection_ty,
)?;

let tcx = ecx.tcx();
let ty::Dynamic(bounds, _, _) = *goal.predicate.self_ty().kind() else {
bug!("expected object type in `consider_object_bound_candidate`");
};
nested_goals.extend(
structural_traits::predicates_for_object_candidate(
tcx,
goal.predicate.projection_ty.trait_ref(tcx),
bounds,
)
.into_iter()
.map(|pred| goal.with(tcx, pred)),
);

let subst_certainty = ecx.evaluate_all(nested_goals)?;

ecx.eq_term_and_make_canonical_response(
goal,
subst_certainty,
assumption_projection_pred.term,
)
})
} else {
Err(NoSolution)
}
}

fn consider_impl_candidate(
ecx: &mut EvalCtxt<'_, 'tcx>,
goal: Goal<'tcx, ProjectionPredicate<'tcx>>,
39 changes: 39 additions & 0 deletions compiler/rustc_trait_selection/src/solve/trait_goals.rs
Original file line number Diff line number Diff line change
@@ -86,6 +86,45 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
}
}

fn consider_object_bound_candidate(
ecx: &mut EvalCtxt<'_, 'tcx>,
goal: Goal<'tcx, Self>,
assumption: ty::Predicate<'tcx>,
) -> QueryResult<'tcx> {
if let Some(poly_trait_pred) = assumption.to_opt_poly_trait_pred()
&& poly_trait_pred.def_id() == goal.predicate.def_id()
{
// FIXME: Constness and polarity
ecx.probe(|ecx| {
let assumption_trait_pred =
ecx.instantiate_binder_with_infer(poly_trait_pred);
let mut nested_goals = ecx.eq(
goal.param_env,
goal.predicate.trait_ref,
assumption_trait_pred.trait_ref,
)?;

let tcx = ecx.tcx();
let ty::Dynamic(bounds, _, _) = *goal.predicate.self_ty().kind() else {
bug!("expected object type in `consider_object_bound_candidate`");
};
nested_goals.extend(
structural_traits::predicates_for_object_candidate(
tcx,
goal.predicate.trait_ref,
bounds,
)
.into_iter()
.map(|pred| goal.with(tcx, pred)),
);

ecx.evaluate_all_and_make_canonical_response(nested_goals)
})
} else {
Err(NoSolution)
}
}

fn consider_auto_trait_candidate(
ecx: &mut EvalCtxt<'_, 'tcx>,
goal: Goal<'tcx, Self>,
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use rustc_data_structures::fx::FxHashMap;
use rustc_hir::{Movability, Mutability};
use rustc_infer::traits::query::NoSolution;
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable};

use crate::solve::EvalCtxt;

@@ -233,3 +234,62 @@ pub(crate) fn extract_tupled_inputs_and_output_from_callable<'tcx>(
}
}
}

pub(crate) fn predicates_for_object_candidate<'tcx>(
tcx: TyCtxt<'tcx>,
trait_ref: ty::TraitRef<'tcx>,
object_bound: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
) -> Vec<ty::Predicate<'tcx>> {
let mut requirements = vec![];
requirements.extend(
tcx.super_predicates_of(trait_ref.def_id).instantiate(tcx, trait_ref.substs).predicates,
);
for item in tcx.associated_items(trait_ref.def_id).in_definition_order() {
if item.kind == ty::AssocKind::Type {
requirements.extend(tcx.item_bounds(item.def_id).subst(tcx, trait_ref.substs));
}
}

let mut replace_projection_with = FxHashMap::default();
for bound in object_bound {
let bound = bound.no_bound_vars().expect("higher-ranked projections not supported, yet");
if let ty::ExistentialPredicate::Projection(proj) = bound {
let proj = proj.with_self_ty(tcx, trait_ref.self_ty());
let old_ty = replace_projection_with.insert(
proj.projection_ty,
proj.term.ty().expect("expected only types in dyn right now"),
);
assert_eq!(
old_ty,
None,
"{} has two substitutions: {} and {}",
proj.projection_ty,
proj.term,
old_ty.unwrap()
);
}
}

requirements.fold_with(&mut ReplaceProjectionWith { tcx, mapping: replace_projection_with })
}

struct ReplaceProjectionWith<'tcx> {
tcx: TyCtxt<'tcx>,
mapping: FxHashMap<ty::AliasTy<'tcx>, Ty<'tcx>>,
}

impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ReplaceProjectionWith<'tcx> {
fn interner(&self) -> TyCtxt<'tcx> {
self.tcx
}

fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
if let ty::Alias(ty::Projection, alias_ty) = *ty.kind()
&& let Some(replacement) = self.mapping.get(&alias_ty)
{
*replacement
} else {
ty.super_fold_with(self)
}
}
}
20 changes: 20 additions & 0 deletions tests/ui/traits/new-solver/object-unsafety.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// compile-flags: -Ztrait-solver=next

trait Setup {
type From: Copy;
}

fn copy<U: Setup + ?Sized>(from: &U::From) -> U::From {
*from
}

pub fn copy_any<T>(t: &T) -> T {
copy::<dyn Setup<From=T>>(t)
//~^ ERROR the trait bound `dyn Setup<From = T>: Setup` is not satisfied
}

fn main() {
let x = String::from("Hello, world");
let y = copy_any(&x);
println!("{y}");
}
19 changes: 19 additions & 0 deletions tests/ui/traits/new-solver/object-unsafety.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
error[E0277]: the trait bound `dyn Setup<From = T>: Setup` is not satisfied
--> $DIR/object-unsafety.rs:12:12
|
LL | copy::<dyn Setup<From=T>>(t)
| ^^^^^^^^^^^^^^^^^ the trait `Setup` is not implemented for `dyn Setup<From = T>`
|
note: required by a bound in `copy`
--> $DIR/object-unsafety.rs:7:12
|
LL | fn copy<U: Setup + ?Sized>(from: &U::From) -> U::From {
| ^^^^^ required by this bound in `copy`
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
|
LL | pub fn copy_any<T>(t: &T) -> T where dyn Setup<From = T>: Setup {
| ++++++++++++++++++++++++++++++++

error: aborting due to previous error

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